28.11.13 — 12:33
Создал в общихМакетах Макет типа ActiveDocument с расширением doc. Не получает с ним работать. Подскажите что не так. Делаю на УФ. Вот код
&НаКлиенте
Процедура Печать(Команда)
ПолучитьМакетНаСервере(«ПФ_DOC_Договор»);
//MSWord = Договор.Получить;
КонецПроцедуры
Процедура ПолучитьМакетНаСервере(ИмяМакета)
Договор = ПолучитьОбщийМакет(ИмяМакета);
MSWord = Договор.Получить;
конецпроцедуры
Выскакивает ошибка
Ошибка при вызове метода контекста (Получить)
MSWord = Договор.Получить();
1 — 28.11.13 — 12:34
&НаСервере забыл?
2 — 28.11.13 — 12:36
Если не указываешь директиву, то по умолчанию означает что код будет выполняться на сервере
3 — 28.11.13 — 12:37
Да я пробовал и &НаСервере и &НаСервереБезКонтекста. Все-равно не получается
4 — 28.11.13 — 12:40
А зачем ты пишешь Получить()? Ведь у тебя это не хранилище…
5 — 28.11.13 — 12:43
(4) А как надо сделать что бы заработало
6 — 28.11.13 — 12:44
MSWord = ПолучитьОбщийМакет(ИмяМакета);
не?
7 — 28.11.13 — 12:48
А потом как начать работать с документом что бы можно было заполнять поля в нем?
8 — 28.11.13 — 12:49
Я ставлю
Документ = MSWord.Application.Documents(1);
Документ.Activate();
У меня сразу выскакивает
Поле объекта не обнаружено (Application)
Документ = MSWord.Application.Documents(1);
Весь инет облазил. У всех работает. Может я что с начала не правильно делал
9 — 28.11.13 — 12:52
(8) А ты что, заполнять его на сервере собрался?
10 — 28.11.13 — 12:53
Ну вроде как так надо делать.
11 — 28.11.13 — 13:03
(10) Я уже сильно не помню причины, но я делаю через временный файл.
Код такой (у меня макет хранится в ХЗ):
&НаКлиенте
Процедура СформироватьПечатнуюФорму(ДоговорКонтрагента, Макет)
ДанныеДляПечати = ПолучитьДанныеДляПечати(ДоговорКонтрагента, Макет);
ХранилищеМакета = ДанныеДляПечати[0];
Если ХранилищеМакета.Представление = «ХранилищеМакета» Тогда
ИмяФайла = ПолучитьИмяВременногоФайла();
ХранилищеМакета.Значение.Записать(ИмяФайла); //Записываем макет во временный файл.
ДанныеДляПечати.Удалить(ХранилищеМакета);
Иначе
Сообщить(«Ошибка получения макета», СтатусСообщения.Внимание);
Возврат;
КонецЕсли;
Попытка
MSWord = ПолучитьCOMОбъект(, «Word.Application»); //Если Word уже открыт, то подключаемся к нему.
Исключение
Попытка
MSWord = Новый COMОбъект(«Word.Application»); //Открываем Word.
Исключение
Сообщить(«Ошибка формирования печатной формы. Скорее всего на Вашем компьютере не установлен Microsoft Word.», СтатусСообщения.Внимание);
Сообщить(ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
КонецПопытки;
Документ = MSWord.Documents.Open(ИмяФайла); //Открываем макет из временного файла.
MSWord.Selection.WholeStory(); //Выделяем весь документ.
MSWord.Selection.Copy(); //Копируем выделенное в буфер.
Документ.Close(); //Закрываем документ.
УдалитьФайлы(ИмяФайла); //Удаляем временный файл.
Документ = MSWord.Documents.Add(); //Создаем новый документ.
MSWord.Selection.PasteAndFormat(19); //Вставляем в документ содержимое из буфера с форматом исходного документа.
MSWord.ActiveDocument.Range(0,1).Copy(); //Очищаем буфер обмена, чтоб лишних вопросов при закрытии документа не задавал.
MSWord.Selection.HomeKey(6); //Переводим курсор в начало документа.
//Производим заполнение заменяемых полей
Замена = Документ.Content.Find;
Для Каждого ЗаменяемоеПоле Из ДанныеДляПечати Цикл
Замена.Execute(ЗаменяемоеПоле.Значение, Ложь, Истина, Ложь, , , Истина, , Ложь, ЗаменяемоеПоле.Представление, 2);
КонецЦикла;
//Проверяем, остались ли незаполненные заменяемые поля
Если Замена.Execute(«{«) Тогда
Сообщить(«В печатной форме «»» + СокрЛП(Макет.Наименование) + «»» заполнены не все заменяемые поля.», СтатусСообщения.Внимание);
КонецЕсли;
Документ.Saved = Истина; //Помечаем документ как сохраненный, чтобы при закрытии не выдавался запрос на сохранение документа
Если Элементы.ФормаПечатьНаПринтер.Пометка Тогда
Документ.PrintOut(Истина, , , , , , , Макет.КоличествоКопий, , , , Истина);
Документ.Close();
Иначе
MSWord.Visible = Истина;
MSWord.Activate();
КонецЕсли;
КонецПроцедуры //СформироватьПечатнуюФорму()
12 — 28.11.13 — 13:06
(11) Спасибо. Попробую. Надеюсь заработает
13 — 28.11.13 — 13:08
ПолучитьДанныеДляПечати() выполняется &НаСервере
14 — 02.12.13 — 12:03
&НаСервереБезКонтекста
Процедура ПолучитьМакетНаСервере()
Макет = ПолучитьОбщийМакет(«ПФ_DOC_Договор»);
Ком = Макет.Получить();
Ком.Application.Visible = 1;
конецПроцедуры
&НаКлиенте
Процедура Напечатать(Команда)
Состояние(НСтр(«ru = ‘Выполняется формирование печатных форм'»));
ПолучитьМакетНаСервере();
КонецПроцедуры
Ошибка при вызове метода контекста (Получить)
Ком = Макет.Получить();
Что не так? Сделал как написано в книге «Профессиональная разработка в системе 1С».
В общих макетах создал .doc макет, в него скопировал содержимое документа. Пытаюсь его получить, вылетает ошибка. Помоги разобрать, как сделать через ActiveDocument
15 — 02.12.13 — 12:04
Тип созданного макета — ActiveDocument
16 — 02.12.13 — 12:06
Делаю все это во внешней обработке
17 — 02.12.13 — 12:08
(14) что за ошибка?
18 — 02.12.13 — 12:09
Ошибка при вызове метода контекста (Получить)
Ком = Макет.Получить();
19 — 02.12.13 — 12:10
хз, попробуй так
текОбъект = ЭтаФорма.РеквизитФормыВЗначение(«Объект»);
Макет = текОбъект.ПолучитьМакет(«ПФ_DOC_Договор»);
20 — 02.12.13 — 12:11
(19) Делал, не получается
21 — 02.12.13 — 12:15
(14) (18) Ты (4) Читал?
&НаСервереБезКонтекста
Процедура ПолучитьМакетНаСервере()
Ком = ПолучитьОбщийМакет(«ПФ_DOC_Договор»);
Ком.Application.Visible = 1;
конецПроцедуры
&НаКлиенте
Процедура Напечатать(Команда)
Состояние(НСтр(«ru = ‘Выполняется формирование печатных форм'»));
ПолучитьМакетНаСервере();
КонецПроцедуры
Так работает?
22 — 02.12.13 — 12:17
(4) я читал
23 — 02.12.13 — 12:19
(21) Сделал так, выскочила другая ошибка
Поле объекта не обнаружено (Application)
Ком.Application.Visible = 1;
Я еще раз повторюсь, делал по примеру, который приведен в книге.
24 — 02.12.13 — 12:20
Ну если не работает, как там приведен, вот я спрашиваю у Вас все, форумчане. Так как считаю этот форум одним из лучших по 1С, почти всегда тут можно найти решение проблем
25 — 02.12.13 — 12:23
(23) А, точно, Получить() надо. Только что посмотрел, как раньше делал. Тогда у меня версия, что у тебя в макете что-то не то…
Cube
26 — 02.12.13 — 12:26
+(25) Если оставить только суть, то:
Макет = ПолучитьМакет(«Макет»);
MSWord = Макет.Получить();
…
Документ = MSWord.Application.Documents(1);
Документ.Activate();
…
MSWord.Application.Visible = Истина;
MSWord.Activate();
Создал в общихМакетах Макет типа ActiveDocument с расширением doc. Не получает с ним работать. Подскажите что не так. Делаю на УФ. Вот код Выскакивает ошибка Ошибка при вызове метода контекста (Получить)
Если не указываешь директиву, то по умолчанию означает что код будет выполняться на сервере
Да я пробовал и &НаСервере и &НаСервереБезКонтекста. Все-равно не получается
А зачем ты пишешь Получить? Ведь у тебя это не хранилище…
А как надо сделать что бы заработало
А потом как начать работать с документом что бы можно было заполнять поля в нем?
Документ.Activate; У меня сразу выскакивает Поле объекта не обнаружено (Application) Весь инет облазил. У всех работает. Может я что с начала не правильно делал
А ты что, заполнять его на сервере собрался?
Ну вроде как так надо делать.
Я уже сильно не помню причины, но я делаю через временный файл. Код такой (у меня макет хранится в ХЗ): Исключение Сообщить(«Ошибка формирования печатной формы. Скорее всего на Вашем компьютере не установлен Microsoft Word.», СтатусСообщения.Внимание);
Спасибо. Попробую. Надеюсь заработает
ПолучитьДанныеДляПечати выполняется &НаСервере
&НаСервереБезКонтекста Состояние(НСтр(«ru = ‘Выполняется формирование печатных форм'»)); Ошибка при вызове метода контекста (Получить) Что не так? Сделал как написано в книге «Профессиональная разработка в системе 1С». В общих макетах создал .doc макет, в него скопировал содержимое документа. Пытаюсь его получить, вылетает ошибка. Помоги разобрать, как сделать через ActiveDocument
Тип созданного макета — ActiveDocument
Делаю все это во внешней обработке
Ошибка при вызове метода контекста (Получить)
Ты Читал? &НаСервереБезКонтекста Так работает?
Сделал так, выскочила другая ошибка Поле объекта не обнаружено (Application) Я еще раз повторюсь, делал по примеру, который приведен в книге.
Ну если не работает, как там приведен, вот я спрашиваю у Вас все, форумчане. Так как считаю этот форум одним из лучших по 1С, почти всегда тут можно найти решение проблем
А, точно, Получить надо. Только что посмотрел, как раньше делал. Тогда у меня версия, что у тебя в макете что-то не то…
+ Если оставить только суть, то:
Тэги: 1С 8
Комментарии доступны только авторизированным пользователям
<?php // Полная загрузка сервисных книжек, создан 2023-01-05 12:44:55
global $wpdb2;
global $failure;
global $file_hist;
///// echo '<H2><b>Старт загрузки</b></H2><br>';
$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
///// echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}
$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
///// echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}
/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
///// echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
///// echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist); ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7]; ////получаем размер файла
$m_mtime_file=$masiv_data_file[9]; ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file
///// echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
///// echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
///// echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);
if ($results)
{ foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));
////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
///// echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
///// echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}
////загружаем данные
$table='vin_history'; // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация // (путь от корня web-сервера)
$delim=';'; // Разделитель полей в CSV файле
$enclosed='"'; // Кавычки для содержимого полей
$escaped='
Related Posts
Получение логина и пароля техподдержки 1С из базы
Класс для вывода отчета в Excel
Счет-фактура для УПП
Библиотека классов для создания внешней компоненты 1С на C#
Акт об оказании услуг (со скидками) — внешняя печатная форма для Управление торговлей 11.1.10.86
Прайс-лист с артикулом в отдельной колонке
46 Comments
-
-
Один вопрос — когда помещаете во временнное хранилище не указываете адрес:
Если Word Тогда
//Помещать во временное хранилище не обязательно
Возврат ПоместитьВоВременноеХранилище(СтруктураВсехДокументов);
Иначе
Возврат ТабДокумент;
КонецЕсли;
ПоместитьВоВременноеХранилище(<Данные>, <Адрес>)
Параметры:
<Данные> (обязательный)
Тип: Произвольный.
Данные, которые необходимо поместить во временное хранилище.
<Адрес> (необязательный)
Тип: УникальныйИдентификатор; Строка.
Уникальный идентификатор формы, во временное хранилище которой надо поместить данные и вернуть новый адрес. Или адрес во временном хранилище, по которому надо поместить данные. Адрес должен получен ранее с помощью данного метода.
В случае, если передается УникальныйИдентификатор формы или адрес в хранилище, то значение будет автоматически удалено после закрытия этой формы.
Если передан УникальныйИдентификатор, не являющийся уникальным идентификатором формы, то значение будет удалено после завершения сеанса пользователя.
Если параметр не указан, помещенное значение будет удалено после очередного запроса сервера из общего модуля, при контекстном и неконтекстном серверном вызове из формы, при серверном вызове из модуля команды или при получении формы.
Reply ↓
-
(1) Franco, в «Альтернативы:» я уже дал ссылку на эту статью
(2) w.r., А в чём вопрос то? Боитесь, что значение будет удалено раньше чем вы успеете его использовать?
Кстати для 2-го примера <Передача макет Word (Двоичные данные) с сервера на клиент> можно и не писать
Возврат ПоместитьВоВременноеХранилище(СтруктураВсехДокументов);
//Можно писать:
Возврат СтруктураВсехДокументов;
,т.к. в СтруктураВсехДокументов попадает СтруктураПараметров, в которую в свою очередь попадает только строковые значения (какое значение на какое заменить). Для строковых значений не нужно сериализовать значение. Именно эта строка написана для примера. Если вы так-же как и я в СтруктураПараметров будете писать только строковые значения, то можно и не помещать во временное хранилище.
Reply ↓
-
(3)
Да, будет удалено.
Вы, кстати, еще используете без адреса временное хранилище здесь:
&НаСервере
Функция ПолучитьМакетСКлиента(Имя)
Возврат ПоместитьВоВременноеХранилище(Документы.ПисьмоНаОплату.ПолучитьМакет(«ПисьмоНаОплатуWordДвоичныеДанные»));
КонецФункции
И вот тут лучше будет передавать в качестве адреса для временного хранилища идентификатор формы. Те вот так:
&НаСервере
Функция ПолучитьМакетСКлиента(Имя)
Возврат ПоместитьВоВременноеХранилище(Документы.ПисьмоНаОплату.ПолучитьМакет(«ПисьмоНаОплатуWordДвоичныеДанные»), УникальныйИдентификатор);
КонецФункции
Reply ↓
-
(3)
Оффтоп. Еще совет — если не используете форму на сервере, тогда лучше использовать &НаСервереБезКонтекста
Reply ↓
-
(4) w.r., ну в общем случае вы конечно правы и вообще правильно написать:
&НаСервере
Функция ПолучитьМакетСКлиента(Имя)
Возврат ПоместитьВоВременноеХранилище(Документы.ПисьмоНаОплату.ПолучитьМакет(«ПисьмоНаОплатуWordДвоичныеДанные»), УникальныйИдентификатор);
КонецФункции
Но у меня написан код:
&НаКлиенте
…
СтруктураНаПечать = ПолучитьИзВременногоХранилища(ПечатьПисьма(Объект.Ссылка,Неопределено,Истина));
…
&НаСервере
Функция ПолучитьМакетСКлиента(Имя)
Возврат ПоместитьВоВременноеХранилище(Документы.ПисьмоНаОплату.ПолучитьМакет(«ПисьмоНаОплатуWordДвоичныеДанные»));
КонецФункции
Показать
У меня даже нет переменной где бы я запомнил адрес во временном хранилище, т.к. как только я делаю «ПоместитьВоВременноеХранилище» потом сразу делаю «ПолучитьИзВременногоХранилища». Между этими двумя действиями нет ни строчки кода, поэтому пропасть значение до получения не может. Кстати код у меня установлен в рабочей базе и всё работает.
Если же кому-то исходя из специфики задачи нужен будет этот адрес не единожды и он его будет потом использовать вплоть до закрытия формы, то конечно корректней использовать УникальныйИдентификатор.
Другими словами: замечание хорошее, но в моей конкретной реализации задачи ничего не потеряется даже без уникального идентификатора.
Спасибо за замечание, статью позже чуть допишу (вдруг кому-то и правда адрес во временном хранилище нужен будет не единожды и сразу).
Reply ↓
-
(6)
У меня даже нет переменной где бы я запомнил адрес во временном хранилище, т.к. как только я делаю «ПоместитьВоВременноеХранилище» потом сразу делаю «ПолучитьИзВременногоХранилища». Между этими двумя действиями нет ни строчки кода, поэтому пропасть значение до получения не может.
Вы не внимательно читали видимо описание. Написано:
значение будет удалено после очередного запроса сервера из общего модуля
Т.е. любое выполнение регламентного задания или иных действий параллельно работающих пользователей, использующих общие модули, в промежутке выполнения вашего кода на форме очистит временное хранилище, куда вы поместили макет еше до получения из хранилища
Reply ↓
-
(6)
Еще могут отработать подписки на события. Сам сталкивался давным давно с этим, когда начинал работать со временным хранилищем
Вообще, передача объектов с клиента на сервер у 1С реализвона хреново. Например, из клиентского общего модуля нельзя получить имена реквизитов формы, тк нельзя передать форму с клиента на сервер, если ты не находишься собственно в самой форме. А процедура ПолучитьРеквизиты для УФ работает только на сервере. И тут никакие временные хранилища не помогут уже
Reply ↓
-
-
(8) w.r., Ну уж за час у нас точно куча подписок было отработано в рабочей базе))
Давайте на минуту представим, что
Если параметр не указан, помещенное значение будет удалено, после очередного запроса сервера из общего модуля, при контекстном и неконтекстном серверном вызове из формы, при серверном вызове из модуля команды или при получении формы.
мы понимаем как
любое выполнение регламентного задания или иных действий параллельно работающих пользователей, использующих общие модули, в промежутке выполнения вашего кода на форме очистит временное хранилище
Первый вопрос: почему у меня тогда ничего не удалилось ни в течении часа ни в течении 10 минут на рабочей базе БП 3.0?
Второе: методы «ПоместитьФайл, ПоместитьФайлы, ПоместитьВоВременноеХранилище» получается вообще некорректно использовать без Уникального идентификатора, т.к. любое действие любого пользователя базы может привести к очистке адреса хранилища. На большом количестве народу (1000+ одновременно работающих пользователей) данные методы будут давать корректный (не очищенный) адрес только в 50% случаев, а то и меньше. Не думаю, что это так, тем более я на практике привёл пару исчерпывающих тестов.
У меня: Бухгалтерия предприятия, редакция 3.0 (3.0.41.64) , 1С:Предприятие 8.3 (8.3.6.2332).
Reply ↓
-
(3) прошу прощения за невнимательность
Reply ↓
-
(10)
Протестировал. Правда не очищается временное хранилище причем даже с вызовом сервера, если находишься в текущей форме.
У меня между методами
ПоместитьВоВременноеХранилище()
и
ПолучитьИзВременногоХранилища()
, выполнился метод
СоединенияИБВызовСервера.ПараметрыБлокировкиСеансов()
. Может 8.3.6 так работает, на 8.2 точно очищалось. Попробую протестировать на базе с 8.2 и отпишусь
Reply ↓
-
(10)
у вас вариант базы клиент-серверный или файловый?
Reply ↓
-
(13) w.r., конечно клиент-серверный. Как я написал в статье для файловой базы можно вообще не заморачиваться, выполнил на сервере запрос, чтобы получить данные, получил Word (не важно откуда) заполнил и показал пользователю. Ничего передавать на клиент не надо, лепота))
Reply ↓
-
А как у вас в варианте с ActiveDocument работает на сервере эта конструкция?
Макет = ПолучитьМакет(«ПисьмоНаОплатуWord»);
MSWord = Макет.Получить();
В макет у меня попадает ОболочкаActiveDocument, а Получить() падает с ошибкой вызова метода контекста.
В СП написано, что для этого типа метод Получить() доступен только на толстом клиенте.
Reply ↓
-
(15) Kirill_K, у меня рабочего кода на руках нет, ибо сейчас в отпуске. Сделал обработку (см вложение). где всего пару строк кода. У меня дома на 8.2 (файловая база) не падает на методе «Получить()»! На работе практически самая свежая 8.3 и там тоже никакой ошибки на этой строчке (файловая или клиент-серверная).
Тупо в обработке нажмите на «Команда1» — будет ошибка?
Reply ↓
-
(16) 8.2 клиент-серверная падает, а в файловой 8.3 ком-объект создается.
Значит, обновляться нужно, спасибо.
Reply ↓
-
(17) Kirill_K, код который написан у меня в статье я писал для клиент-серверной 8.3.6. Всё работало. Поэтому после обновления возможно и у вас заработает. Но для чистоты эксперимента я когда выйду на работу попробую на клиент-серверной обработку из 16 сообщения.
Reply ↓
-
(17) Kirill_K, попробовал в серверном режиме на 8.3.6.2332: ничего не вырубается. После строчки:
MSWord = Макет.Получить();
в переменной MSWord появляется COMОбъект. Походу Вам правильный совет — это обновиться.
Кстати в справке даже в 8.3.6.2332 написано, что метод Получить() якобы работает только в толстом клиенте:)
Reply ↓
-
Не пойму в чем дело?
ошибка при вызове метода контекста save типы не совпадают
Reply ↓
-
(21) gmtv, есть пример-обработка, выслал её в личку.
Reply ↓
-
(18) доброго дня — у меня 8.3.6 клиент сервер — запустил вашу обработку стопорится на Получить(). В чем может быть проблема?
Reply ↓
-
(23) micha26,
1. У вас офис на сервере установлен?
2. Если да, то на пользователе под которым работает агент 1С нормально запускается?
3. Обработка из 16-го сообщения работает?
Reply ↓
-
(24) офис установлен, пользователю даны права на запуск офиса, нет стопорится также.
Reply ↓
-
(25) micha26, обработка маленькая, на какой из строк стопорится?:
Word = Новый COMОбъект(«Word.Application»);
Word.Visible=1;
Документ = Word.Documents.Add();
ИмяВрем = ПолучитьИмяВременногоФайла(«.docx»);
Документ.SaveAs(ИмяВрем);
Сообщить(ИмяВрем);
И ещё: а если в обработке переделать процедуру с серверной на клиентскую: тоже не работает?
Reply ↓
-
На SaveAs, без разницы клиент или серверная.
Reply ↓
-
(27) micha26,
Это решение пробовали?:
Возможная ошибка на сервере при вызове метода SaveAs:
Ошибка при вызове метода контекста (SaveAs)
Документ.SaveAs(ИмяВрем);
по причине:
Произошла исключительная ситуация (Microsoft Word): Ошибка команды
Мне поначалу эту ошибку не удалось победить, поэтому я стал использовать ДвоичныеДанные. Позже нашёл решение проблемы: необходимо по пути C:WindowsSysWOW64configsystemprofile и C:WindowsSystem32configsystemprofile создать папки Desktop. Туда никаких файлов никто не пишет, похоже, программе важен факт наличия этой папки. Решение нашёл по ссылке: http://devtrainingforum.v8.1c.ru/forum/thread.jsp?id=581998&threadtype=0
Reply ↓
-
(28) да ходил по этой ссылке, не помогло. Макет с двоичными данными делал та же фигня получается.
Reply ↓
-
(29) micha26, даже не знаю что тогда… Такое ощущение, что проблема не на стороне 1С. Может антивирус или брандмауэр что-то блокирует? Попробуйте хотя-бы локально все по-вырубать и на клиенте SaveAS() сделать.
Reply ↓
-
(30) отрубал все для примера сделал следующее:
&НаСервере
Функция ПолучитьСтруктуруДанных()
ФайлWord = Справочники.Партнеры.ПолучитьМакет(«РазовыйДоговорДв»); //двоичные данные на актив забил болт
АдресФайла = ПоместитьВоВременноеХранилище(ФайлWord);
Возврат АдресФайла;
КонецФункции
&НаКлиенте
Процедура ПечатьРазовогоДоговора(Команда)
ПутьКФайлу = «D:DocРазовый договор.doc»;
СтруктураДанных = ПолучитьСтруктуруДанных(); // значение = e1cib/tempstorage/7230a82d-ab89-4e08-b05a-e7122515ab93
ФайлWord = ПолучитьИзВременногоХранилища(ПутьКФайлу); // Ошибка при вызове метода контекста (ПолучитьИзВременногоХранилища)
//всякая ересь по получению данных
Показать
Один хрен не работает…куда копать уже не представляю.
Reply ↓
-
(31) micha26, похоже у вас ошибка в строчке:
//На момент исполнения кода в переменной ПутьКФайлу содержится значение:»D:DocРазовый договор.doc»
ФайлWord = ПолучитьИзВременногоХранилища(ПутьКФайлу);
Вместо ПутьКФайлу вам нужно использовать СтруктураДанных
Reply ↓
-
(32) да похоже верно — проверю.
Reply ↓
-
(33) micha26,
&НаКлиенте
Процедура ПечатьРазовогоДоговора(Команда)
ПутьКФайлу = «D:DocРазовый договор.doc»;
СтруктураДанных = ПолучитьСтруктуруДанных();
ФайлWord = ПолучитьИзВременногоХранилища(СтруктураДанных);
ФайлWord.Записать(ПутьКФайлу); // Файл записывается в папку
Попытка
Word = Новый COMОбъект(«Word.Application»);
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
Договор = Word.Open(ПутьКФайлу); // Здесь останавливается Word.Open — метод объекта не обнаружен в принципе можно убрать на фиг.
КонецПроцедуры
Показать
Что-то я нить потерял, как теперь данные заполнить в документе.
Reply ↓
-
(34) Вообщем переделал все на фиг — сохраняю шаблоны в выделенную папку на сервере, делаю запрос на сервере, сохраняю значения в реквизиты для печати и на клиенте заменой загоняю значения в шаблон. Шустро работает.
Reply ↓
-
(34) micha26,
Вместо Word = Новый COMОбъект(«Word.Application»); и Open(ПутьКФайлу); можно использовать Документ = ПолучитьCOMОбъект(ИмяВрем); (как в принципе и написано у меня в статье)
ФайлWord.Записать(ПутьКФайлу); // Файл записывается в папку
Попытка
Word = Новый COMОбъект(«Word.Application»);
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
Договор = Word.Open(ПутьКФайлу);
ИмяВрем = ПолучитьИмяВременногоФайла(«.docx»);
ДвоичныеДанныеМакета.Записать(ИмяВрем);
Попытка
Документ = ПолучитьCOMОбъект(ИмяВрем);
Что касается метода Open: он вроде используется так: Word.Documents.Open(ПутьКФайлу).
Reply ↓
-
(36) я таким макаром сделал:
&НаКлиенте
Попытка
Word = Новый COMОбъект(«Word.Application»);
Исключение
Сообщить(«Ошибка: » + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
ЗаполнитьДанныеДоговора(); //запрос на сервере
//Путь к шаблону
Word.Documents.Add(«D:DocРазовыйДоговор.doc»);
ШаблонWord = Word.ActiveDocument;
//далее заполнение заменой
Показать
Как бы заработало и шаблоны шустро править можно
Reply ↓
-
(37) micha26, ну в принципе как вариант. Я в альтернативах в конце статьи об этом варианте тоже упомянул:
2. Можно сохранить файл Word в общую папку и с клиента его просто получать. Главное, чтобы файл никто не удалил.
Reply ↓
-
(38) за что вам премного благодарен ))))
Reply ↓
-
А кстати если кому интересен полный код стучитесь в личку.
Reply ↓
-
Прекрасная статья! Всё понятно и доходчиво написано.
По правде говоря мне пришло уведомление на гневный комментарий в моей теме со ссылкой на вашу статью где меня «ну просто опустили» (дословная цитата). Странно, прочитал всё от корки до корки, нигде никто меня не опускал)))) Гневный комментарий тоже удалён))) Видимо его автор сильно неуверен в себе, раз позволяет себе такое.
Насчёт кода на сервере, которым я записывал файл, вот он (в начале лета приводил в порядок всю свою базу наработок):
//Получает макет ActiveDocument и записывает его в файл
Функция ПолучитьМакет(Документ) Экспорт
Каталог = ПараметрыСеанса.ТекущийПользователь.РабочийКаталог;
Каталог = ?(Прав(Каталог,1) = «», Каталог, Каталог+»»);
Если ЗначениеЗаполнено(Каталог) Тогда
Попытка
ПолноеИмяФайла = Каталог+Документ.Номер+».doc»;
Макет = Документы.ДоговорыКонтрагентов.ПолучитьМакет(«ActiveDocument»);
Макет.Записать(ПолноеИмяФайла);
Возврат ПолноеИмяФайла;
Исключение
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = «Не удалось записать файл «+ОписаниеОшибки();
Сообщение.Сообщить();
Возврат Неопределено;
КонецПопытки;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = «Не указан каталог. Сохранение файла невозможно»;
Сообщение.Сообщить();
Возврат Неопределено;
КонецЕсли;
КонецФункции // ()
Показать
Спасибо, что поставили ссылку на статью. Рад, что хоть чем-то смог помочь. Сейчас отредактирую её и приведу данный листинг кода.
Reply ↓
-
(41) CeHbKA,
Макет = Документы.ДоговорыКонтрагентов.ПолучитьМакет(«ActiveDocument»);
Макет.Записать(ПолноеИмяФайла);
Так вот как оказывается можно ещё сохранить! Не заметил, что у ОболочкаActiveDocument есть метод Записать. Обязательно обновите статью, т.к. многие сваливаются на методе SaveAs, а Записать() у ОболочкаActiveDocument фактически является альтернативой
Reply ↓
-
-
Понять не могу только у меня спотыкается на этом месте:
ОбъектВ = ПолучитьМакет(«СервисныйДоговор»).Получить(); // метод получить не обнаружен
ОбъектВ получается это оболочка активного документа…
Reply ↓
-
(44) Попробуйте обработку из (16) сообщения и посмотрите цепочку сообщений связанных с (16). Похоже это ваш случай (у вас Платформа 8.2 же?)
Reply ↓
-
(16) {ВнешняяОбработка.СоздатьТестWord.Форма.Форма.Форма(26)}: Ошибка при вызове метода контекста (Получить)
MSWord = Макет.Получить();
Reply ↓
-
Столкнулся с проблемой, при заполнении Active doc на сервере. Если два пользователя одновременно запустят печать , произойдет наложение активных документов, и либо все зависнет, либо заполнится некорректно. Если ли способ разделить заполнение, чтобы оно работало параллельно?
Reply ↓
Leave a Comment
Ваш адрес email не будет опубликован. Обязательные поля помечены *
(Здесь действие происходит в модуле формы)
&НаСервере
Функция ЗаполнитьМакетНаСервере()
ОбработкаОб = РеквизитФормыВЗначение("Объект");
АктивныйДокумент = ОбработкаОб.ПолучитьМакет("МакетДоговораActiveDocument"); //ОболочкаActiveDocument
КомОбъект = АктивныйДокумент.Получить(); //метод работает на сервере
////////////ПЕРВЫЙ ВАРИАНТ ЗАПОЛНЕНИЯ ПАРАМЕТРОВ////////////
//инициализируем переменные, чтобы если какие-то из них окажутся незаполненными, то не отображалась текстовая ошибка в документе
КомОбъект.Variables("ДатаПриема").Value = " ";
КомОбъект.Variables("Организация").Value = " ";
КомОбъект.Variables("ЮрАдрес").Value = " ";
КомОбъект.Variables("Должность").Value = " ";
КомОбъект.Variables("ИНН_КПП_ОГРН").Value = " ";
КомОбъект.Variables("Адрес").Value = " ";
КомОбъект.Variables("ФИОСотрудника").Value = " ";
//заполнение переменных реальными значениями
КомОбъект.Variables("ДатаПриема").Value = "22 сентября 2017г";
КомОбъект.Variables("Организация").Value = "Миросса";
КомОбъект.Variables("ЮрАдрес").Value = "Санкт Петербург, Невский пр, д. 102";
КомОбъект.Variables("Должность").Value = "Генеральный директор";
КомОбъект.Variables("Адрес").Value = "Санкт Петербург, Невский пр, д. 102";
КомОбъект.Variables("ФИОСотрудника").Value = "Сергей Петрович";
//Книга.ActiveWindow.Visible = Истина; //?
//Книга.Activate(); //?
КомОбъект.Fields.Update();
////////////ВТОРОЙ ВАРИАНТ ЗАПОЛНЕНИЯ ПАРАМЕТРОВ////////////
Replace = КомОбъект.Content.Find;
FindText = "<<ФиоСокр>>"; // что искать - имя_шаблона
MatchCase = Ложь; // использовать регулярные выражения
MatchWholeWord = Истина; // искать слово целиком
MatchWildcards = Ложь; // испоьзовать регулярные выражения
MatchSoundsLike = Неопределено; // искать созвучные
MatchAllWordForms = Неопределено; // искать все формы слова
Forward = Истина; // искать вперед
Wrap = Неопределено; // что должен вернуть Find-объект
Format_ = Ложь; // использовать форматирование
ReplaceWith = "С.П."; // текст, на который надо заменить имя_шаблона
//Replace.Execute(FindText,Ложь,Истина,Ложь,,,Истина,,Ложь,ReplaceWith );
Replace.Execute(
FindText,
MatchCase,
MatchWholeWord,
MatchWildcards,
MatchSoundsLike,
MatchAllWordForms,
Forward,
Wrap,
Format_,
ReplaceWith );
Replace = КомОбъект.Content.Find; //перед каждым вызовом Execute()
Replace.Execute(
"<<ИНН_КПП_ОГРН>>",
MatchCase,
MatchWholeWord,
MatchWildcards,
MatchSoundsLike,
MatchAllWordForms,
Forward,
Wrap,
Format_,
"7802022" );
имяФ = ПолучитьИмяВременногоФайла("doc");
КомОбъект.SaveAS(имяФ); //здесь возможна ошибка (http://infostart.me/public/568913/)
Двоичные = новый ДвоичныеДанные(имяФ);
//в web клиенте Двоичные.Записать() не работает, поэтому
//Адрес = новый ХранилищеЗначения(Двоичные);
//возврат Адрес;
//а затем на клиенте:
//ПолучитьФайл(Адрес, "ИмяФайла.doc", Истина); //файл скачивается в браузере
КомОбъект.Application.Quit(); //закрыть Word
КомОбъект = 0;
Возврат Двоичные;
КонецФункции
&НаКлиенте
Процедура ЗапускПриложения(КодВозврата, ДополнительныйПараметр) Экспорт
КонецПроцедуры
&НаКлиенте
Процедура Печать(Команда)
//Попытка
// Ворд = Новый COMОбъект("Word.Application");
//Исключение
// Сообщить("Установи Word..");
// Возврат;
//КонецПопытки;
Двоичные = ЗаполнитьМакетНаСервере();
имяФ = ПолучитьИмяВременногоФайла("doc"); //в web клиенте не работает
Двоичные.Записать(имяФ); //в web клиенте не работает
//ЗапуститьПриложение(имяФ); //error Использование синхронных методов на клиенте запрещено!
Оповещение = Новый ОписаниеОповещения("ЗапускПриложения", ЭтотОбъект);
НачатьЗапускПриложения(Оповещение, имяФ,, Ложь); //ложь - не дожидаемся завершения приложения (в процедуру ЗапускПриложения всё равно заходим, сразу же
КонецПроцедуры
Пример использования ActiveDocument _Word.
Как создать поля-параметры в Word
1 Выбираем участок(кусок текста) для параметра, например: «Организация»(на первой картинке она уже скрыта) , а можно удалить его и спозиционироваться на этом месте.
2 В меню Word, переходим на «Вставка», далее «Экспресс-блоки», далее «Поле»
3 В открывшемся диалоговом окне, выбираем тип «DocVariable»
4 Назначаем имя, в моем случае «NomerDogovora»
5. Жмем «Ок», когда окно закроется, вы скорей всего не увидите изменений, так как скрыт «Word kod», нажмите Alt+F9, что бы открыть код.
6. Таким образом создаете все нужные Вам параметры



Ссылки: http://www.modber.ru/catalog/item3340.html, http://j008.ru/ps/027_ActiveDocument
WordОвские файлы *doc, *docx — это ZIP-архивы ((*xls и *xlsx тоже)). Меняем расширение docx на zip и распаковываем архив. Получим структуру папокфайлов. Текст файлов в формате XML. Удобно редактировать текст, менять картинки(папка wordmedia). И собираем обратно, архивируем.
СоздатьКаталог(«C:времКаткат01»);
Архив = Новый ЧтениеZipФайла();
Архив.Открыть(«C:времКаткат01наименование.zip»);
Архив.ИзвлечьВсе(«C:времКаткат01Unpacked», РежимВосстановленияПутейФайловZIP.Восстанавливать);
Архив.Закрыть();
// что-то делаем
//ПутьИзменяемыйФайл = «C:времКаткат01Unpackedwordmediaimage1.png»; //для docx
//файл = новый файл(ПутьИзменяемыйФайл);
//Если НЕ Файл.Существует() Тогда
//
//КонецЕсли;
Архиватор = Новый ЗаписьZipФайла(«C:времКаткат01наименование2.zip», «», «»);
Архиватор.Добавить(«C:времКаткат01Unpacked*.*», РежимСохраненияПутейZIP.СохранятьОтносительныеПути, РежимОбработкиПодкаталоговZIP.ОбрабатыватьРекурсивно);
Архиватор.Записать();
УдалитьФайлы(«C:времКаткат01»);