08.01.13 — 17:24
Всем привет! Печ. форма формируется через Word. Открывается файл Word, там делаются замены после чего он сохраняется. Все отлично работало, пока не перенес базу на SQL.
Причем, если на этом сервере развернуть эту же базу в файловом варианте — все работает. А на SQL — нет.
Пробовал давать какие-угодно права пользователю, от имени которого запускается Агент сервера. Запускал его и под встроенной учеткой и под админом… нифига.
Вот фрагмент кода, который перестает работать на SQL:
Word = Новый COMОбъект(«Word.Application»);
Word.Visible = 0;
Документ = Word.Documents.Open(ИмяФайлаШаблона);
Fnd = Word.ActiveDocument.Range().Find;
Fnd.ClearFormatting();
Fnd.Forward = -1;
Выдает ошибку: «{ВнешняяОбработка.ФормированиеПоШаблону.МодульОбъекта(379)}: Ошибка при получении значения атрибута контекста (ActiveDocument)
Fnd = Word.ActiveDocument.Range().Find;
по причине:
Произошла исключительная ситуация (Microsoft Word): Данная команда недоступна, так как не открыт ни один документ.»
Пожалуйста, помогите разобраться в чем дело.
1 — 08.01.13 — 17:28
ну а путь к файлу у тебя какой? файл сам где лежит?
2 — 08.01.13 — 17:29
Сам Word установлен?
Что выдаст ПолучитьCOMОбъект(«», «Word.Application»)
или ПолучитьCOMОбъект(«d:temptemp.docx»)
3 — 08.01.13 — 17:29
ИмяФайлаШаблона — существует ли файл по этому пути, и доступен ли?
4 — 08.01.13 — 17:30
Сначала делал так:
ИмяФайлаШаблона = КаталогВременныхФайлов() + «ШаблонДоговора.docx»;
Потом переделал жестко:
ИмяФайлаШаблона = «C:UsersPublicDocuments» + «ШаблонДоговора.docx»;
Но не помогло.
5 — 08.01.13 — 17:31
Да, Word установлен. Если в файловом варианте развернуть, все работает, документ отлично формируется и открывается.
6 — 08.01.13 — 17:32
Ответь на (2)
7 — 08.01.13 — 17:32
Только выполни на сервере
8 — 08.01.13 — 17:33
Кода запускаешь файловую базу, доступны ком-обхекты локальной системы. Если сервер 1С находится на другой машине, откуда ему знать про «C:UsersPublicDocuments» терминального сервера или локальной машины?
9 — 08.01.13 — 17:38
Разумеется, я сто раз проверил существование файла, все права на него и все такое. В разные места его клал, админские права раздавал.
Запускаю я все на одном и том же сервере. И Word и 1C установлены на той машине, на которой я работаю.
Насчет (2): в первом случае результат тот же — «ни открыт ни один документ», во втором случае другая ошибка: «{ВнешняяОбработка.ФормированиеПоШаблону.МодульОбъекта(374)}: Ошибка при вызове метода контекста (ПолучитьCOMОбъект)
Word = ПолучитьCOMОбъект(ИмяФайлаШаблона);
по причине:
Ошибка получения объекта COM: Фильтр сообщений выдал диагностику о занятости приложения.»
10 — 08.01.13 — 17:40
У тебя и сервер 1С на той же машине стоит?
11 — 08.01.13 — 17:41
может как вариант повис на сервере COMОбъект Ворда. посмотри в процессах.
12 — 08.01.13 — 17:46
Vladal, Да, я когда разбирался с проблемой, установил все на одну машину. Сервер 1С, SQL и Word. На ней и разбираюсь.
zladenuw, ты прав. Там висела целая пачка процессов Word. Я их выбил, но теперь другая ошибка:
{ВнешняяОбработка.ФормированиеПоШаблону.МодульОбъекта(374)}: Ошибка при вызове метода контекста (ПолучитьCOMОбъект)
Word = ПолучитьCOMОбъект(ИмяФайлаШаблона);
по причине:
Ошибка получения объекта COM: Операция прервана
13 — 08.01.13 — 17:52
(12) Значит что-то из дочерних процессов может висеть и блокировать.
Скорее всего, он ответил на твой последний запрос com-объекта, что его прервали. Повтори через время или для верности перегрузи компьютер.
14 — 08.01.13 — 17:55
Я с проблемой второй день бьюсь и не раз перезагружал и даже переустанавливал платформу.
Если использовать «Word = Новый COMОбъект(«Word.Application»);», то COM объект создается. Т.е. по идее с СОМ все в порядке.
Для полной ясности скажу что стоит:
Платформа 8.2.17.153.
Сервер 1С — х64
Сервер SQL — 2012
Печатная форма для УТ 11. Хотя непонятно, какое это все имеет отношение к COM объекту… Короче, танцы с бубном продолжаются, спасибо за участие!
15 — 08.01.13 — 21:51
Если танцы с бубном не помогут, есть вариант без ворда если у тебя простая замена по тексту на нужные значения.
Переименовываешь файл docx в zip, извлекаешь в папку, находишь в подпапках файл с данными в формате xml, производишь в нем замены и назад выполняешь упаковку и переименование.
16 — 09.01.13 — 00:56
Pashkaa, это всем бубнам бубен ))) Я уж лучше на файловой версии все оставлю, чем так. Думаю, решение рано или поздно найдется. Буду с разными платформами экспериментировать. Вряд ли я единственный пытаюсь документ Word сформировать из базы 1С на SQL. А судя по тому, что в поиске ничего подобного нет, то ситуация не популярная и легко все может заработать на другой системе или конфигурации. Такие мысли у меня.
17 — 09.01.13 — 01:58
(16) напиши сетевую папку. Диск С: лучше не писать. Там есть такая фигня в правах как передача прав подчиненным папкам. Наследование.
То есть если ваш админ для диска С: задал неполные права твоему пользователю, то хоть ты застрелись, но хотя и будешь «давать какие-угодно права пользователю» на папку C:UsersPublicDocuments всё равно приоритет у прав на диск С:, которые и применятся.
18 — 09.01.13 — 03:52
(4) Посмотри пути.
Выполняется наверняка на сервере, значит далеко не факт, что у учетки запуска rphost-a есть права на путь-файл.
19 — 11.01.13 — 02:35
Разобрался. Кто бы мог подумать… Как я уже писал, это УТ 11 — т.е. управляемые формы. Перенес выполнение всех операций с объектом «Word = Новый COMОбъект(«Word.Application»)» с сервера на клиент — все заработало. Не спешите кидать тухлыми помидорами типа «конечно, Word не откроется на стороне сервера». Но раньше-то как-то открывался. Именно это меня и пустило по ложному следу. Выходит, доступность методов COM объектов на файловом сервере и SQL — разная.
Какой я сделал вывод:
Что касается конкретно метода Word.Documents.Open — если база файл-серверная, методу все равно где выполняться, на клиенте или на сервере. Документ открывается и показывается ни смотря ни на что. Но когда я перешел на SQL, метод ошибки выдавать не стал и внешне отрабатывает как я писал выше. Но если выполняется на стороне сервера — ничего не открывает и дальнейшее обращение к документу дает ошибку, а на стороне клиента — открывает.
20 — 11.01.13 — 07:43
сколько можно на эти грабли наступать.
http://infostart.ru/public/165910/
21 — 11.01.13 — 10:32
МихаилМ, по-моему не совсем по теме. Сом объект-то создается и остальные методы у него работают. Вы читали ветку или только последнее сообщение?
Сколько можно на эти грабли наступать… Сейчас-то конечно все сразу умные станут. )) Что раньше молчали? Давайте без этого.
22 — 11.01.13 — 10:47
(21)
из (9)>Разумеется, я сто раз проверил существование файла, все права на него и все такое. В разные места его клал, админские права раздавал.
не стыкуется с (19)
СЕсин
23 — 11.01.13 — 11:08
Чем же не стыкуется? В (9) я мудрил с самим файлом, а в (19) перенес выполнение кода с сервера на клиент. Короче, флуд пошел…
1С чтение и редактирование файла word (doc, docx), поиск и замена текста
Чтение файла, пример процедуры
&НаСервере Процедура ПрочитатьWordНаСервере() WordПриложение = Новый COMОбъект("Word.Application"); // выведем на экран документ WordПриложение.Visible = Истина; WordПриложение.Documents.Open("G:test.docx"); WordФайл = WordПриложение.ActiveDocument(); // обходим строки документа Для Строка = 1 по WordФайл.Sentences.Count Цикл Текст = WordФайл.Sentences(Строка).Text; Сообщить(Текст); КонецЦикла; WordФайл.Close(); WordПриложение.Quit(); КонецПроцедуры
Поиск и замена текста, пример процедуры
&НаСервере Процедура ЗаменитьТекстВWordПриложениеНаСервере() WordПриложение = Новый COMОбъект("Word.Application"); WordПриложение.Visible = Истина; WordПриложение.Documents.Open("G:test.docx"); WordФайл = WordПриложение.ActiveDocument(); Поиск = WordФайл.Range().Find; ЗаменяемыйТекст = "тест"; ЗаменяющийТекст = "123"; Поиск.Execute(ЗаменяемыйТекст, , , , , , , , ,ЗаменяющийТекст , 2); Поиск.ClearFormatting(); WordФайл.Close(); WordПриложение.Quit(); КонецПроцедуры
Связанные статьи
Это моя первая статья на данном портале, но попытаюсь изложить все понятно и подробно.
Долгое время у меня заняло создание такой вот внешней обработки. Есть очень много примеров, как сделать подобное на неуправляемых формах (2.0) и очень мало информации касательно управляемых(3.0), по крайней мере я многого найти не смог в доступе. Создание подобное обработки выглядит вполне несложно, если производить все действия на сервере, как это было с 2.0, но в нашем случае необходимо инициализировать открытие документа на клиенте, чему сильно мешает отсутствие возможности передать макет Active Document с сервера на клиент.
Итак, пойдем по порядку. Подобная информация уже есть в сети, но для полноты картины кратко разъясню регистрацию обработки в системе:
1. Открываем модуль объекта обработки и создаем там Функцию СведенияОВнешнейОбработке() (естественно экспортную):
СведенияОВнешнейОбработке()
Как мы видим, использовать будем ВызовКлиентскогоМетода, по скольку открыть файл нужно будет на компьютере пользователя.
Далее понадобится создать еще две процедуры здесь же:
2. Функция добавления команды, которую мы вызываем ранее(просто, чтобы все было визуально разделено и не награмождалось скопом в одной функции):
ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = «»)
3. И функция по созданию этой самой таблицы команд:
(Из комментариев можно подробней понять, для чего используется тот или иной параметр-поле данной таблицы)
На этом настройка регистрации внешней обработки в нужной вам конфигурации закончена.
Далее. Самое интересное: создание, заполнение и вывод макета клиенту.
Первое, что нам необходимо сделать, это создать макет нашего документа(Изображение 3). Макет понадобится двоичный, т.к. обычный мы на клиент не передадим(как я и говорил ранее). Заменяем нужные данные в шаблоне, перед загрузкой в обработку, «Параметрами», у меня они выглядят так, на примере: «{Сотрудник}»(кавычки не учитывать), после чего загружаем в Обработку-Макет.
Теперь в модуле формы создаем процедуру, которая будет вызвана при обращении к печати именно в таком виде(за исключением содержимого, заполнять можете как вам угодно), процедура так же должна быть экспортной и на клиенте, так как вызывается из конфигурации и выполнение назначено на клиентской стороне:
Печать(ИдентификаторКоманды, МассивОбъектов)
Макет я собираю и вызываю в отдельной процедуре, обязательно на клиенте.
СобратьМакет(СсылкаНаОбъект)
Для сбора макета нам понадобится получить этот самый макет уже с сервера. Передаю я его через временное хранилище:
ПолучитьМакетСервер(ИмяМакета)
Далее нужно получить данные для заполнения макета, естественно на сервере, по скольку может понадобиться обратиться к сторонним регистрам и справочникам, если нет, то можно выполнить и на клиенте, получив ссылку на интересующий нас объект:
ПолучитьДанные(СсылкаНаОбъект)
Данные складываем в структуру,где ключ — имя параметра в макете(без фигурных скобок), а значение — собственно значение, которое необходимо подставить.
На этом завершается наше создание. Вы можете скачать обработку в готовом виде, в ней также реализован запуск через форму обработки, то есть с помощью открытия обработки без регистрации ее в конфигурации. Надеюсь, моя статья многим поможет и окажется полезной. Спасибо большое за внимание!
В данной статье рассмотрим достаточно простой и удобный способ формирования документов Word из 1С. Сама по себе 1С формировать документы Word “не умеет”, и для работы с такими документами используется собственно MS Word. Поэтому вначале нужно определенным образом подготовить документ, а после загрузить его в макет двоичных данных в 1С.
Для корректной работы данного способа необходимо, чтобы на компьютере, где происходит формирование документа, был установлен MS Office. Также, документ формируется на клиенте, с тем чтобы вывести его на экран пользователю. Но возможно формирование и на сервере, если на сервере установлен Word – например, для прикрепления файлов к справочникам.
Подготовка шаблона Word
В документе Word можно вставлять поля специального типа DocVariables. Это можно сделать либо вставив соответствующий фрагмент текста, либо через графический интерфейс. На примере Word 2016, это делается через меню Вставка / Экспресс блоки/ Поле. В списке доступных полей нас интересует DocVariable. Указываем нужное имя и жмем ОК.
Для скрытия / отображения кодов полей в документе, жмем Alt + F9. Для экономии времени, можно просто копировать нужные поля и вставлять в нужные места документа. Чтобы создать новую переменную документа, достаточно просто в кавычках заменить имя.
Формирование документа Word из 1С
После того, как шаблон готов, его нужно загрузить в виде макета с типом “Двоичные данные”. Это можно сделать в обработке, в общем макете, в справочнике и т.д. Рассмотрим на примере хранения макета в обработке.
Сперва нужно создать ComОбъект Word, сохранить файл из макета во временный файл, и прочитать его в Word. Далее мы переходим к заполнению переменных DocVariablе любым удобным способом – можно явно указывать нужные имена переменных и их значения, а можно заранее подготовить структуру данных и в цикле заполнить по этой структуре. Далее необходимо обновить поля в документе Word, скрыть коды полей, если вдруг они включены, и отобразить документ. Для доступа к конкретному полю DocVariable используется код вида ComОбъектWord.Variables(“СтроковоеИмяПеременной”).Value. Делаем это в попытке, на случай, если поля с таким именем в Word нет.
&НаКлиенте Процедура ВывестиДокументWord(Команда) МакетШаблонWord = ПолучитьМакетНаСервере(); ОбъектWord = Новый COMОбъект("Word.Application"); ИмяВременногоФайла = ПолучитьИмяВременногоФайла(); МакетШаблонWord.Записать(ИмяВременногоФайла); ДокументWord = ОбъектWord.Documents.Add(ИмяВременногоФайла); //Удобнее всего заполнять через структуру СтруктураДанных = Новый структура("ДатаДокумента, ТекстИз1С", Формат(ТекущаяДата(),"ДЛФ=DD"), "Какой-то текст из 1С"); Для Каждого КлючИЗначение Из СтруктураДанных Цикл Попытка ДокументWord.Variables(КлючИЗначение.Ключ).Value = КлючИЗначение.Значение; Исключение КонецПопытки; КонецЦикла; ДокументWord.Fields.Update(); ОбъектWord.ActiveWindow.View.ShowFieldCodes = False; ОбъектWord.Visible = True; КонецПроцедуры &НаСервере Функция ПолучитьМакетНаСервере() Возврат РеквизитФормыВЗначение("Объект").ПолучитьМакет("Макет"); КонецФункции
Настройка системы для формирования документов Word или Excel на стороне сервера
Допустим, необходимо формировать документ офисного пакета Microsoft Office на стороне сервера, то есть от имени сервера 1С, но не всегда установка «из коробки» позволяет выполнять данную операцию. так как обычно происходит исключительная ошибка создания COM-объекта. В этом случае требуется более тонкая настройка системы в целом. Настройка заключается в установке прав доступа сервера 1С к DCOM-приложению и папке Desktop. Рассмотрим процесс настройки.
Откройте оснастку «Службы компонентов», для этого в командной строке выполните команду dcomcnfg (или comexp.msc /32 для 64-разрядной Windows, см. рисунок 1).
Рисунок 1. Запуск оснастки «Службы компонентов» |
В узле Настройка DCOM найдите элемент Microsoft Excel Application(если хотите выполнять формирование документов Excel) или элемент Документ Microsoft Office Word 97 — 2003(если хотите выполнять формирование документов Word), нажмите правой кнопкой мыши и выберите пункт Свойства (см. рисунок 2).
Рисунок 2. Выбор приложения DCOM |
Перейдите на вкладку Безопасность, установите пункт Настроить в секции Разрешения на запуск и активацию и нажмите на кнопку Изменить (см. рисунок 3).
Рисунок 3. Установка разрешения на запуск и аквтивацию |
В открывшемся окне добавьте пользователя, от имени которого работает сервер 1С (для 1С версии 8.2 — USR1CV82, для версии 8.3 — USR1CV83), и разрешите ему все действия (см. рисунок 4).
Рисунок 4. Установка разрешений для пользователя системы |
Далее создайте папку Desktop по адресу С:WindowsSystem32configsystemprofile для 32-разрядной Windows (C:WindowsSysWOW64configsystemprofile для 64-разрядной) если она не существует и наделите пользователя, от имени которого работает сервер 1С, полными правами доступа на эту папку. Для этого нажмите правой кнопкой на папку Desktop и выберите пункт Свойства. В окне свойств папки перейдите на вкладку Безопасность и нажмите Изменить (см. рисунок 5).
Рисунок 5. Настройка правд доступа к папке Desktop |
В открывшемся окне добавьте пользователя, аналогичного для DCOM-приложения (см. рисунок 6).
Рисунок 6. Установка прав на папку для пользователя |
Теперь COM-объект офисного пакета Microsoft Office должен создаваться на стороне сервера и формировать новый документ без всяких проблем.
Вступайте в мою группу помощник программиста.
В ней мы обсуждаем программирование в 1С.
2017-12-19T18:36:38+00:00<<< XML ZIP WORD DBF HTTP FTP ТекстовыйДокумент ТабличныйДокумент
Скачать эти примеры в виде тестовой базы (как загрузить, как исследовать)
Скачать шаблон bill.dotx, который используется в примерах ниже.
Как создавать такие шаблоны самому.
Оглавление (нажмите, чтобы раскрыть)
/// Как создать документ Word на основе шаблона из 1с 8.3, 8.2 &НаКлиенте Функция КакСоздатьДокументWordНаОсновеШаблона(ПутьКШаблону) // В шаблоне уже расставлены поля с определенными // именами, например, org_name, inn, kpp и т.д. // Наша задача - заполнить эти поля и сохранить // этот шаблон в виде вордовкского файла с // расширением docx; // Сам шаблон мы создали по инструкции отсюда: // helpme1s.ru/kak-sozdavat-shablony-word-dlya-ispolzovaniya-v-1s // Или взяли готовым отсюда: // helpme1s.ru/files/ref/bill.dotx ПриложениеВорд = Новый COMОбъект("Word.Application"); ОбъектШаблон = ПриложениеВорд.Documents.Add(ПутьКШаблону); Для Каждого Поле Из ОбъектШаблон.Fields Цикл ПолноеИмяПоля = Поле.Code.Text; // Наши предопределенные поля имеют такой // вид: " MERGEFIELD org_name * MERGEFORMAT". // Наша задача - вытащить из этой конструкции org_name // (ну или другое имя, которое мы задали в ворде). Если (Найти(ПолноеИмяПоля, " MERGEFIELD") = 1) Тогда ПозицияСлеша = Найти(ПолноеИмяПоля, "*"); КороткоеИмяПоля = СокрЛП(Сред(ПолноеИмяПоля, 12, ПозицияСлеша - 12)); ЗначениеПоля = ""; Если КороткоеИмяПоля = "id" Тогда ЗначениеПоля = "1"; ИначеЕсли КороткоеИмяПоля = "bill_date" Тогда ЗначениеПоля = Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy"); ИначеЕсли КороткоеИмяПоля = "org_name" Тогда ЗначениеПоля = "ООО ""Ромашка"""; ИначеЕсли КороткоеИмяПоля = "inn" Тогда ЗначениеПоля = "1234567890"; ИначеЕсли КороткоеИмяПоля = "kpp" Тогда ЗначениеПоля = "123456789"; Иначе // ... и так все нужные поля КонецЕсли; Если ЗначениеПоля <> "" Тогда Поле.Select(); ОбъектШаблон.Application.Selection.TypeText(ЗначениеПоля); КонецЕсли; КонецЕсли; КонецЦикла; // Запишем файл в папку "Мои документы" пользователя ФайлДляЗаписи = КаталогДокументов() + "helpme1c_ru_word_test.docx"; // Если такой файл уже существует - удалим его. УдалитьФайлы(ФайлДляЗаписи); // Сохраняем шаблон как документ Word с расширением docx. ОбъектШаблон.SaveAs(ФайлДляЗаписи); // Не забываем закрыть приложение Word. ОбъектШаблон.Application.Quit(); Возврат ФайлДляЗаписи; КонецФункции /// Скачать и выполнить эти примеры на компьютере
Скачать эти примеры в виде тестовой базы (как загрузить, как исследовать)
Скачать шаблон bill.dotx, который используется в примерах ниже.
Как создавать такие шаблоны самому.
Работа с Word в языке 1С 8.3, 8.2 (в примерах)
<<< XML ZIP WORD DBF HTTP FTP ТекстовыйДокумент ТабличныйДокумент
С уважением, Владимир Милькин (преподаватель школы 1С программистов и разработчик обновлятора).
Как помочь сайту: расскажите (кнопки поделиться ниже) о нём своим друзьям и коллегам. Сделайте это один раз и вы внесете существенный вклад в развитие сайта. На сайте нет рекламы, но чем больше людей им пользуются, тем больше сил у меня для его поддержки.
Нажмите одну из кнопок, чтобы поделиться: