Как передать документ Word (ActiveDocument или ДвоичныеДанные) с сервера на клиент




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-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='\

46 Comments

  1. Franco

    вот ещё по теме Вот это поворот

    Reply
  2. w.r.

    Один вопрос — когда помещаете во временнное хранилище не указываете адрес:

    Если Word Тогда
    //Помещать во временное хранилище не обязательно
    Возврат ПоместитьВоВременноеХранилище(СтруктураВсехДокументов);
    Иначе
    Возврат ТабДокумент;
    КонецЕсли;
    

    ПоместитьВоВременноеХранилище(<Данные>, <Адрес>)

    Параметры:

    <Данные> (обязательный)

    Тип: Произвольный.

    Данные, которые необходимо поместить во временное хранилище.

    <Адрес> (необязательный)

    Тип: УникальныйИдентификатор; Строка.

    Уникальный идентификатор формы, во временное хранилище которой надо поместить данные и вернуть новый адрес. Или адрес во временном хранилище, по которому надо поместить данные. Адрес должен получен ранее с помощью данного метода.

    В случае, если передается УникальныйИдентификатор формы или адрес в хранилище, то значение будет автоматически удалено после закрытия этой формы.

    Если передан УникальныйИдентификатор, не являющийся уникальным идентификатором формы, то значение будет удалено после завершения сеанса пользователя.

    Если параметр не указан, помещенное значение будет удалено после очередного запроса сервера из общего модуля, при контекстном и неконтекстном серверном вызове из формы, при серверном вызове из модуля команды или при получении формы.

    Reply
  3. klinval

    (1) Franco, в «Альтернативы:» я уже дал ссылку на эту статью

    (2) w.r., А в чём вопрос то? Боитесь, что значение будет удалено раньше чем вы успеете его использовать?

    Кстати для 2-го примера <Передача макет Word (Двоичные данные) с сервера на клиент> можно и не писать

    Возврат ПоместитьВоВременноеХранилище(СтруктураВсехДокументов);
    //Можно писать:
    Возврат СтруктураВсехДокументов;

    ,т.к. в СтруктураВсехДокументов попадает СтруктураПараметров, в которую в свою очередь попадает только строковые значения (какое значение на какое заменить). Для строковых значений не нужно сериализовать значение. Именно эта строка написана для примера. Если вы так-же как и я в СтруктураПараметров будете писать только строковые значения, то можно и не помещать во временное хранилище.

    Reply
  4. w.r.

    (3)

    Да, будет удалено.

    Вы, кстати, еще используете без адреса временное хранилище здесь:

    &НаСервере
    Функция ПолучитьМакетСКлиента(Имя)
    Возврат ПоместитьВоВременноеХранилище(Документы.ПисьмоНаОплату.ПолучитьМакет(«ПисьмоНаОплатуWordДвоичныеДанные»));
    КонецФункции
    

    И вот тут лучше будет передавать в качестве адреса для временного хранилища идентификатор формы. Те вот так:

    &НаСервере
    Функция ПолучитьМакетСКлиента(Имя)
    Возврат ПоместитьВоВременноеХранилище(Документы.ПисьмоНаОплату.ПолучитьМакет(«ПисьмоНаОплатуWordДвоичныеДанные»), УникальныйИдентификатор);
    КонецФункции
    
    Reply
  5. w.r.

    (3)

    Оффтоп. Еще совет — если не используете форму на сервере, тогда лучше использовать &НаСервереБезКонтекста

    Reply
  6. klinval

    (4) w.r., ну в общем случае вы конечно правы и вообще правильно написать:

    &НаСервере
    Функция ПолучитьМакетСКлиента(Имя)
    Возврат ПоместитьВоВременноеХранилище(Документы.ПисьмоНаОплату.ПолучитьМакет(«ПисьмоНаОплатуWordДвоичныеДанные»), УникальныйИдентификатор);
    КонецФункции

    Но у меня написан код:

    &НаКлиенте
    …
    СтруктураНаПечать = ПолучитьИзВременногоХранилища(ПечатьПисьма(Объект.Ссылка,Неопределено,Истина));
    …
    &НаСервере
    Функция ПолучитьМакетСКлиента(Имя)
    Возврат ПоместитьВоВременноеХранилище(Документы.ПисьмоНаОплату.ПолучитьМакет(«ПисьмоНаОплатуWordДвоичныеДанные»));
    КонецФункции

    Показать

    У меня даже нет переменной где бы я запомнил адрес во временном хранилище, т.к. как только я делаю «ПоместитьВоВременноеХранилище» потом сразу делаю «ПолучитьИзВременногоХранилища». Между этими двумя действиями нет ни строчки кода, поэтому пропасть значение до получения не может. Кстати код у меня установлен в рабочей базе и всё работает.

    Если же кому-то исходя из специфики задачи нужен будет этот адрес не единожды и он его будет потом использовать вплоть до закрытия формы, то конечно корректней использовать УникальныйИдентификатор.

    Другими словами: замечание хорошее, но в моей конкретной реализации задачи ничего не потеряется даже без уникального идентификатора.

    Спасибо за замечание, статью позже чуть допишу (вдруг кому-то и правда адрес во временном хранилище нужен будет не единожды и сразу).

    Reply
  7. w.r.

    (6)

    У меня даже нет переменной где бы я запомнил адрес во временном хранилище, т.к. как только я делаю «ПоместитьВоВременноеХранилище» потом сразу делаю «ПолучитьИзВременногоХранилища». Между этими двумя действиями нет ни строчки кода, поэтому пропасть значение до получения не может.

    Вы не внимательно читали видимо описание. Написано:

    значение будет удалено после очередного запроса сервера из общего модуля

    Т.е. любое выполнение регламентного задания или иных действий параллельно работающих пользователей, использующих общие модули, в промежутке выполнения вашего кода на форме очистит временное хранилище, куда вы поместили макет еше до получения из хранилища

    Reply
  8. w.r.

    (6)

    Еще могут отработать подписки на события. Сам сталкивался давным давно с этим, когда начинал работать со временным хранилищем

    Вообще, передача объектов с клиента на сервер у 1С реализвона хреново. Например, из клиентского общего модуля нельзя получить имена реквизитов формы, тк нельзя передать форму с клиента на сервер, если ты не находишься собственно в самой форме. А процедура ПолучитьРеквизиты для УФ работает только на сервере. И тут никакие временные хранилища не помогут уже

    Reply
  9. klinval
    Reply
  10. klinval

    (8) w.r., Ну уж за час у нас точно куча подписок было отработано в рабочей базе))

    Давайте на минуту представим, что

    Если параметр не указан, помещенное значение будет удалено, после очередного запроса сервера из общего модуля, при контекстном и неконтекстном серверном вызове из формы, при серверном вызове из модуля команды или при получении формы.

    мы понимаем как

    любое выполнение регламентного задания или иных действий параллельно работающих пользователей, использующих общие модули, в промежутке выполнения вашего кода на форме очистит временное хранилище

    Первый вопрос: почему у меня тогда ничего не удалилось ни в течении часа ни в течении 10 минут на рабочей базе БП 3.0?

    Второе: методы «ПоместитьФайл, ПоместитьФайлы, ПоместитьВоВременноеХранилище» получается вообще некорректно использовать без Уникального идентификатора, т.к. любое действие любого пользователя базы может привести к очистке адреса хранилища. На большом количестве народу (1000+ одновременно работающих пользователей) данные методы будут давать корректный (не очищенный) адрес только в 50% случаев, а то и меньше. Не думаю, что это так, тем более я на практике привёл пару исчерпывающих тестов.

    У меня: Бухгалтерия предприятия, редакция 3.0 (3.0.41.64) , 1С:Предприятие 8.3 (8.3.6.2332).

    Reply
  11. Franco

    (3) прошу прощения за невнимательность

    Reply
  12. w.r.

    (10)

    Протестировал. Правда не очищается временное хранилище причем даже с вызовом сервера, если находишься в текущей форме.

    У меня между методами

    ПоместитьВоВременноеХранилище()

    и

    ПолучитьИзВременногоХранилища()

    , выполнился метод

    СоединенияИБВызовСервера.ПараметрыБлокировкиСеансов()

    . Может 8.3.6 так работает, на 8.2 точно очищалось. Попробую протестировать на базе с 8.2 и отпишусь

    Reply
  13. w.r.

    (10)

    у вас вариант базы клиент-серверный или файловый?

    Reply
  14. klinval

    (13) w.r., конечно клиент-серверный. Как я написал в статье для файловой базы можно вообще не заморачиваться, выполнил на сервере запрос, чтобы получить данные, получил Word (не важно откуда) заполнил и показал пользователю. Ничего передавать на клиент не надо, лепота))

    Reply
  15. Kirill_K

    А как у вас в варианте с ActiveDocument работает на сервере эта конструкция?

    Макет = ПолучитьМакет(«ПисьмоНаОплатуWord»);
    
    MSWord = Макет.Получить();

    В макет у меня попадает ОболочкаActiveDocument, а Получить() падает с ошибкой вызова метода контекста.

    В СП написано, что для этого типа метод Получить() доступен только на толстом клиенте.

    Reply
  16. klinval

    (15) Kirill_K, у меня рабочего кода на руках нет, ибо сейчас в отпуске. Сделал обработку (см вложение). где всего пару строк кода. У меня дома на 8.2 (файловая база) не падает на методе «Получить()»! На работе практически самая свежая 8.3 и там тоже никакой ошибки на этой строчке (файловая или клиент-серверная).

    Тупо в обработке нажмите на «Команда1» — будет ошибка?

    Reply
  17. Kirill_K

    (16) 8.2 клиент-серверная падает, а в файловой 8.3 ком-объект создается.

    Значит, обновляться нужно, спасибо.

    Reply
  18. klinval

    (17) Kirill_K, код который написан у меня в статье я писал для клиент-серверной 8.3.6. Всё работало. Поэтому после обновления возможно и у вас заработает. Но для чистоты эксперимента я когда выйду на работу попробую на клиент-серверной обработку из 16 сообщения.

    Reply
  19. klinval

    (17) Kirill_K, попробовал в серверном режиме на 8.3.6.2332: ничего не вырубается. После строчки:

    MSWord = Макет.Получить();

    в переменной MSWord появляется COMОбъект. Походу Вам правильный совет — это обновиться.

    Кстати в справке даже в 8.3.6.2332 написано, что метод Получить() якобы работает только в толстом клиенте:)

    Reply
  20. gmtv

    Не пойму в чем дело?

    ошибка при вызове метода контекста save типы не совпадают

    Reply
  21. klinval

    (21) gmtv, есть пример-обработка, выслал её в личку.

    Reply
  22. micha26

    (18) доброго дня — у меня 8.3.6 клиент сервер — запустил вашу обработку стопорится на Получить(). В чем может быть проблема?

    Reply
  23. klinval

    (23) micha26,

    1. У вас офис на сервере установлен?

    2. Если да, то на пользователе под которым работает агент 1С нормально запускается?

    3. Обработка из 16-го сообщения работает?

    Reply
  24. micha26

    (24) офис установлен, пользователю даны права на запуск офиса, нет стопорится также.

    Reply
  25. klinval

    (25) micha26, обработка маленькая, на какой из строк стопорится?:

     Word = Новый COMОбъект(«Word.Application»);
    Word.Visible=1;
    Документ = Word.Documents.Add();
    ИмяВрем = ПолучитьИмяВременногоФайла(«.docx»);
    Документ.SaveAs(ИмяВрем);
    Сообщить(ИмяВрем);
    

    И ещё: а если в обработке переделать процедуру с серверной на клиентскую: тоже не работает?

    Reply
  26. micha26

    На SaveAs, без разницы клиент или серверная.

    Reply
  27. klinval

    (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. micha26

    (28) да ходил по этой ссылке, не помогло. Макет с двоичными данными делал та же фигня получается.

    Reply
  29. klinval

    (29) micha26, даже не знаю что тогда… Такое ощущение, что проблема не на стороне 1С. Может антивирус или брандмауэр что-то блокирует? Попробуйте хотя-бы локально все по-вырубать и на клиенте SaveAS() сделать.

    Reply
  30. micha26

    (30) отрубал все для примера сделал следующее:

    &НаСервере
    Функция ПолучитьСтруктуруДанных()
    ФайлWord = Справочники.Партнеры.ПолучитьМакет(«РазовыйДоговорДв»); //двоичные данные на актив забил болт
    АдресФайла = ПоместитьВоВременноеХранилище(ФайлWord);
    Возврат АдресФайла;
    КонецФункции
    &НаКлиенте
    Процедура ПечатьРазовогоДоговора(Команда)
    ПутьКФайлу = «D:DocРазовый договор.doc»;
    СтруктураДанных = ПолучитьСтруктуруДанных(); // значение = e1cib/tempstorage/7230a82d-ab89-4e08-b05a-e7122515ab93
    ФайлWord = ПолучитьИзВременногоХранилища(ПутьКФайлу); // Ошибка при вызове метода контекста (ПолучитьИзВременногоХранилища)
    //всякая ересь по получению данных

    Показать

    Один хрен не работает…куда копать уже не представляю.

    Reply
  31. klinval

    (31) micha26, похоже у вас ошибка в строчке:

    //На момент исполнения кода в переменной ПутьКФайлу содержится значение:»D:DocРазовый договор.doc»
    ФайлWord = ПолучитьИзВременногоХранилища(ПутьКФайлу);
    

    Вместо ПутьКФайлу вам нужно использовать СтруктураДанных

    Reply
  32. micha26

    (32) да похоже верно — проверю.

    Reply
  33. micha26

    (33) micha26,

    &НаКлиенте
    Процедура ПечатьРазовогоДоговора(Команда)
    ПутьКФайлу = «D:DocРазовый договор.doc»;
    СтруктураДанных = ПолучитьСтруктуруДанных();
    ФайлWord = ПолучитьИзВременногоХранилища(СтруктураДанных);
    ФайлWord.Записать(ПутьКФайлу); // Файл записывается в папку
    Попытка
    Word = Новый COMОбъект(«Word.Application»);
    Исключение
    Сообщить(ОписаниеОшибки());
    Возврат;
    КонецПопытки;
    Договор = Word.Open(ПутьКФайлу); // Здесь останавливается Word.Open — метод объекта не обнаружен в принципе можно убрать на фиг.
    КонецПроцедуры
    

    Показать

    Что-то я нить потерял, как теперь данные заполнить в документе.

    Reply
  34. micha26

    (34) Вообщем переделал все на фиг — сохраняю шаблоны в выделенную папку на сервере, делаю запрос на сервере, сохраняю значения в реквизиты для печати и на клиенте заменой загоняю значения в шаблон. Шустро работает.

    Reply
  35. klinval

    (34) micha26,

    Вместо Word = Новый COMОбъект(«Word.Application»); и Open(ПутьКФайлу); можно использовать Документ = ПолучитьCOMОбъект(ИмяВрем); (как в принципе и написано у меня в статье)

              ФайлWord.Записать(ПутьКФайлу); // Файл записывается в папку
    Попытка
    Word = Новый COMОбъект(«Word.Application»);
    Исключение
    Сообщить(ОписаниеОшибки());
    Возврат;
    КонецПопытки;
    Договор = Word.Open(ПутьКФайлу);

    ИмяВрем = ПолучитьИмяВременногоФайла(«.docx»);
    ДвоичныеДанныеМакета.Записать(ИмяВрем);
    Попытка
    Документ = ПолучитьCOMОбъект(ИмяВрем); 

    Что касается метода Open: он вроде используется так: Word.Documents.Open(ПутьКФайлу).

    Reply
  36. micha26

    (36) я таким макаром сделал:

    &НаКлиенте
    Попытка
    Word = Новый COMОбъект(«Word.Application»);
    Исключение
    Сообщить(«Ошибка: » + ОписаниеОшибки(), СтатусСообщения.Внимание);
    КонецПопытки;
    ЗаполнитьДанныеДоговора(); //запрос на сервере
    //Путь к шаблону
    Word.Documents.Add(«D:DocРазовыйДоговор.doc»);
    ШаблонWord = Word.ActiveDocument;
    //далее заполнение заменой
    

    Показать

    Как бы заработало и шаблоны шустро править можно

    Reply
  37. klinval

    (37) micha26, ну в принципе как вариант. Я в альтернативах в конце статьи об этом варианте тоже упомянул:

    2. Можно сохранить файл Word в общую папку и с клиента его просто получать. Главное, чтобы файл никто не удалил.
    Reply
  38. micha26

    (38) за что вам премного благодарен ))))

    Reply
  39. micha26

    А кстати если кому интересен полный код стучитесь в личку.

    Reply
  40. CeHbKA

    Прекрасная статья! Всё понятно и доходчиво написано.

    По правде говоря мне пришло уведомление на гневный комментарий в моей теме со ссылкой на вашу статью где меня «ну просто опустили» (дословная цитата). Странно, прочитал всё от корки до корки, нигде никто меня не опускал)))) Гневный комментарий тоже удалён))) Видимо его автор сильно неуверен в себе, раз позволяет себе такое.

    Насчёт кода на сервере, которым я записывал файл, вот он (в начале лета приводил в порядок всю свою базу наработок):

    //Получает макет ActiveDocument и записывает его в файл
    Функция ПолучитьМакет(Документ) Экспорт
    
    Каталог = ПараметрыСеанса.ТекущийПользователь.РабочийКаталог;
    Каталог = ?(Прав(Каталог,1) = «», Каталог, Каталог+»»);
    Если ЗначениеЗаполнено(Каталог) Тогда
    Попытка
    ПолноеИмяФайла = Каталог+Документ.Номер+».doc»;
    Макет = Документы.ДоговорыКонтрагентов.ПолучитьМакет(«ActiveDocument»);
    Макет.Записать(ПолноеИмяФайла);
    
    Возврат ПолноеИмяФайла;
    Исключение
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = «Не удалось записать файл «+ОписаниеОшибки();
    Сообщение.Сообщить();
    Возврат Неопределено;
    КонецПопытки;
    Иначе
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = «Не указан каталог. Сохранение файла невозможно»;
    Сообщение.Сообщить();
    Возврат Неопределено;
    КонецЕсли;
    КонецФункции // ()
    

    Показать

    Спасибо, что поставили ссылку на статью. Рад, что хоть чем-то смог помочь. Сейчас отредактирую её и приведу данный листинг кода.

    Reply
  41. klinval

    (41) CeHbKA,

    Макет = Документы.ДоговорыКонтрагентов.ПолучитьМакет(«ActiveDocument»);
    Макет.Записать(ПолноеИмяФайла);

    Так вот как оказывается можно ещё сохранить! Не заметил, что у ОболочкаActiveDocument есть метод Записать. Обязательно обновите статью, т.к. многие сваливаются на методе SaveAs, а Записать() у ОболочкаActiveDocument фактически является альтернативой

    Reply
  42. artms

    Есть ещё вариант заполнения на сервере https://infostart.ru/public/675307/

    Reply
  43. micha26

    Понять не могу только у меня спотыкается на этом месте:

    ОбъектВ = ПолучитьМакет(«СервисныйДоговор»).Получить(); // метод получить не обнаружен
    

    ОбъектВ получается это оболочка активного документа…

    Reply
  44. klinval

    (44) Попробуйте обработку из (16) сообщения и посмотрите цепочку сообщений связанных с (16). Похоже это ваш случай (у вас Платформа 8.2 же?)

    Reply
  45. websamson

    (16) {ВнешняяОбработка.СоздатьТестWord.Форма.Форма.Форма(26)}: Ошибка при вызове метода контекста (Получить)

    MSWord = Макет.Получить();

    Reply
  46. Mihamak

    Столкнулся с проблемой, при заполнении Active doc на сервере. Если два пользователя одновременно запустят печать , произойдет наложение активных документов, и либо все зависнет, либо заполнится некорректно. Если ли способ разделить заполнение, чтобы оно работало параллельно?

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *