Имя: Пароль:
1C
 
VBA и 1С
0 mixqn
 
15.09.08
16:26
Добрый день, дамы и господа!
Возникла проблема при выводе из 1С в MS Excel.
Задача стоит такая: нужно сохранять отчет в файле Excel, но не просто, а с форматированием (главным образом, нужна палитра и группировки). При том, делать это нужно программно.
Ручками это делается просто: формируется отчет в 1С, далее через меню файл - сохранить копию сохраняется в формате Excel нормально и без проблем. Тоже самое происходит, если использовать построитель отчета:

ПостроительОтчета.Вывести(ТабДок);
ТабДок.Записать(ИмяВременныхФайлов, ТипФайлаТабличногоДокумента.XLS);

НО (!!!) вариант сохранения 1 листа не устраивает. Нужно чтобы из 1С выходил отчет с несколькими листами (книга Excel). Для этого сделано так: сначала как написано выше создается файл Excel с отчетом, потом он открывается и данные копируются в книгу Excel на нужный лист следующим образом:

ЛистДанныхЕксель=ПолучитьCOMОбъект(ИмяВременныхФайлов);


АдресОбластиДанных=ЛистДанныхЕксель.ActiveSheet.UsedRange.Address;
ЛистДанныхЕксель.ActiveSheet.UsedRange.Copy();

Ексель.ActiveWorkbook.ActiveSheet.Range(АдресОбластиДанных).Select();
Ексель.ActiveWorkbook.ActiveSheet.Paste();

ЛистДанныхЕксель.Application.DisplayAlerts=Ложь;
ЛистДанныхЕксель.Close();

И все было бы ничего, если бы не 2 НО: при таком копировании теряется палитра и группировки.

Проведя эксперименты с Excel интерактивно удалось понять, как сделать необходимые действия: копировать надо все ячейки, а палитру можно взять из другой книги. Реализуются эти действия следующим кодом VBA:
   
   Cells.Select
   Selection.Copy
   Windows("Книга1").Activate
   Cells.Select
   ActiveSheet.Paste
    ActiveWorkbook.Colors = Workbooks("ЛистExcel.xls").Colors

И казалось бы, все просто: реализуй данный код в 1С и будет тебе счастье.
Ан нет!
Метод Записать табличного документа 1С создает какой-то странный файл экселя (по всей видимости, это не книга, а лист, и по-видимому, работать с ним нужно по-другому).
На строке

ЛистДанныхЕксель.ActiveSheet.Cells.Select();

Выдается ошибка: «Ошибка при вызове метода контекста (Select): Произошла исключительная ситуация (Microsoft Office Excel): Метод Select из класса Range завершен неверно»

И что с этим делать непонятно. Пытался как-то методом научного тыка переставлять команды VB в различном порядке, но безуспешно. Пробовал копировать целиком лист. На VBA это выглядит так:
Sheets("Лист1").Copy Before:=Workbooks("Книга2").Sheets(2)
Как данный текст реализовать в 1С непонятно, т.к. использовать пробелы и := нельзя. Пробовал заменять это скобками и обычным знаком =. Безрезультатно.

Так что вопрос открыт.

P.S. с палитрой вопрос решен. Там все оказалось попроще. Строка
Ексель.ActiveWorkbook.Colors = Ексель.Workbooks(ИмяКниги).Colors;
Выдавала ошибку, но действие совершалось (палитра переносилась), поэтому заключение указанной строки в попытку решило проблему. Так что вот такой текст:

Попытка
Ексель.ActiveWorkbook.Colors = Ексель.Workbooks(ИмяКниги).Colors;
Исключение
КонецПопытки;

привел к желаемому результату.

P.P.S. никто не знает команду очистки буфера обмена? Дело в том, что после вывода отчета данные в буфере остаются и Excel выводил сообщение об этом. Для того чтобы сообщения не было написана строка:
ЛистДанныхЕксель.Application.DisplayAlerts=Ложь;
но это не очень хорошо, т.к. фактически данные в буфере остаются.
1 ТелепатБот
 
гуру
15.09.08
16:26
2 FN
 
15.09.08
16:37
много букв...
толком не понял, че автору нужно
совет навскидку:
1. Копируй не ячейки, а лист
   Sheets("Лист1").Select
   Sheets("Лист1").Copy...
2. Очищать буфер можно так: вместо Copy - делай Cut
3 mixqn
 
15.09.08
17:31
Для тех кто не понял в 2-ух словах что нужно:
1) понять как транслировать команды VB в 1С в принципе (в VB применяются символы, которые 1С не пропустит, как то пробел и двоеточие равно, что с ними делать???)
2) в данном конкретном случае необходимо на листе эксель выделить все, скопировать, вставить на другом листе


FN, как поможет использование Cut для очистки буфера обмена? Вырезанные данные все равно останутся в бефере - вопрос номер раз
Sheets("Лист1").Copy я могу написать. Но вот как этот лист вставить куда нужно вы мне можите сказать? - вопрос номер 2
4 NULLL
 
15.09.08
17:37
(3)
1) Эти символы обозначают именованнные параметры. Идеш в справку по VB и смотриш какой это параметр по счету и его передаеш, все остальные пусты.
5 dk
 
15.09.08
17:38
буфер не обязательно чистить :)
достаточно просто скопировать ячейку
6 kitt
 
15.09.08
17:41
программное сохранение в Эксель:

ТабДок.Записать("С:\Отчет.xls", ТипФайлаТабличногоДокумента.xls)
7 NULLL
 
15.09.08
17:43
(4) +1 В данном случае:


Sub Copy([Before], [After])
   Member of Excel.Sheets


Before:= передает в функцию первый параметр,ты тоже-самое можеш зделать с 1С
8 FN
 
15.09.08
17:45
(3) Как вставить - ну посмотри наконец справку по VB!
По поводу Cut - сам не проверял, но в интерактивном режиме при использовании Cut после вставки - буфер очищается.
9 mixqn
 
15.09.08
17:47
(7) kitt, просьба внимательнее прочитать суть вопроса. Мне не нужно сохранять табличный документ. Мне нужно из одного листа эксель скопировать все и вставить в другой.  

(6) dk, не обязательно. Мы и не чистим. Опять же читайте внимательнее описание выше. Вопрос в том, можно ли его почистить и как это сделать.
(5) NULLL, не понял вас. Приведите пример.
Допустим, как строку

Sheets("Лист1").Copy Before:=Workbooks("Книга2").Sheets(2)

на VB написать в 1С
10 mixqn
 
15.09.08
17:48
(8) аналогичный совет. Посмотрите справку по VB!!!!
11 mixqn
 
15.09.08
17:51
(8)По поводу Cut. Хотя мне и так было очевидно, что буфер не очищается, проверил. Действительно, не очищается. Вырезанное остается в буфере. При желании проверьте - вставлять можно сколько угодно раз пока буфер не очистить принудительно.
12 mixqn
 
15.09.08
17:54
(9) NULLL, таже просьба пример приведите. То что нужно передать параметр я понимаю. Как его передать вы можите мне сказать? Конкретно. На пальцах.
13 Immortal
 
15.09.08
17:55
Sheets("Лист1").Copy(параметры)
14 mixqn
 
15.09.08
17:59
(12)В качестве параметров что передать нужно?
15 kabanoff
 
15.09.08
18:01
У меня такая же фигня с этими скриптами:
Работа с VBscript из 1С 7.7 (проблема при компиляции скрипта VBscript)
Похоже по ОЛЕ функциональность VB несколько ограничена.
16 NULLL
 
15.09.08
18:04
(12) Что на пальцах расказать, как в функию передать первый парамтр, что-ли?
17 dk
 
15.09.08
18:06
буфер надо очистить ради секретности или ради того чтобы вопрос на выходе не задавался?
---
справку по ВБА принципиально не читаешь?
Ексель.ActiveWorkbook.Sheets(1).Copy(Ексель.Workbooks(2).Sheets(2));
18 mixqn
 
15.09.08
18:08
(16) да, совершенно верно. рассказать на пальцах как передать параметр. я уже приводил строку кода на VB. Вот напишите мне ее же только из 1С. Куда и как там запихнуть параметры.
19 mixqn
 
15.09.08
18:10
(15) спасибо! Хоть 1 понимающий человек! К ответу на вопрос я конечно не приблизился, но хотябы меня поняли.
20 kabanoff
 
15.09.08
18:11
ScrptCtrl = Новый "MSScriptControl.ScriptControl";
 ScrptCtrl.Language = "vbscript";
 ScrptCtrl.AddCode("
 |Sub MySub()
 ...Попробуй твой код на VB суда запихнуть
 |End Sub
 |";
 ScrptCtrl.Run("FindAndReplace");

Чем мог, тем помог =)
21 kabanoff
 
15.09.08
18:14
Ай, ошибся!
Вместо:
ScrptCtrl.Run("FindAndReplace")
вставить:
ScrptCtrl.Run("MySub")
конечно же! =)
22 mixqn
 
15.09.08
18:16
(20) я уже думал об этом... Похоже, других вариантов не остается, надо так пробовать. Хотя не хотелось.
23 dk
 
15.09.08
18:17
(19) куда пропал? (17) пробовал?
24 mixqn
 
15.09.08
18:18
(23) Написал так:

ЛистДанныхЕксель.ActiveSheet.Copy(Ексель.ActiveWorkbook.Sheets(1));

Вот что получилось:

Ошибка при вызове метода контекста (Copy): Произошла исключительная ситуация (Microsoft Office Excel): Метод Copy из класса Worksheet завершен неверно
25 dk
 
15.09.08
18:21
Ексель.Workbooks(1).Sheets(1).Copy(Ексель.Workbooks(1).Sheets(1))
26 FN
 
15.09.08
18:23
(25)+ только не Copy, a Paste
27 dk
 
15.09.08
18:28
(26) не, вроде copy просто
28 FN
 
15.09.08
18:31
(27) сначала копи() без параметров, а вот пасте уже с параметром

вроде так
29 mixqn
 
15.09.08
18:33
(25) ОГРОМНЕЙШЕЕ СПАСИБО dk!!!!!!
Этот код работает.
Однако путь все равно "обходной". Если кто-то знает как же всетаки выделить все и скопировать, было бы интересно узнать. Хотябы просто с целью "повышения образованности" )))
Еще раз большое спасибо dk
30 dk
 
15.09.08
18:33
(28) неа, хотя не проверял
(0) автор, ау!
31 mixqn
 
15.09.08
18:33
(26) нет, правильно как в (25)
32 Immortal
 
15.09.08
23:24
я балдею.
чо трудно открыть хелп в редакторе vb?
33 mixqn
 
16.09.08
10:07
(32) если вы думаете, что я не читал хелп, вы ошибаетесь.  Одно из двух, либо я просто не нашел в хелпе то что мне было нужно, либо этот самый хелп бывает разными и у меня не было нужной информации. Я нашел как писать непосредственно на VB. И уже писал о том, что в VB применяются символы которые 1С не пропускает. На что и как эти символы заменять я не нашел в хелпе. Пробы методом тыка не помогли. Это раз. И 2: меня несколько запутало то, что использовалось 2 переменных:

Ексель=Новый ComОбъект("Excel.Application");
и
ЛистДанныхЕксель=ПолучитьCOMОбъект(ИмяВременныхФайлов);

Один из них представляет из себя объект Application, другой - Sheet. Копировать надо было из ЛистДанныхЕксель в книгу Ексель. Вот. Поэтому когда я пробовал различные комбинации первого и второго запутался - все время вылетали ошибки.
Понятно было, что приложение запущено одно и ЛистДанныхЕксель.Application и Ексель это одно и тоже. Но переключаться между книгами по именам почему-то не получалось. Когда я написал как в (25) (правда, конечно, с указанием верных номеров книг и листов), т.е. обращаясь к книгам по номеру все заработало. Хотя, повторюсь, пробовал различные комбинации чего-то аналогичного по смыслу, но пытался обращаться к книгам по именам. Почему-то не получалось.

В общем еще раз спасибо dk за (25) )))))))
Ошибка? Это не ошибка, это системная функция.