Моя публикация предназначена для таких же, как я, "программистов по случаю", которым иногда надо писать что-то для собственных нужд. Подобных обработок на Инфостарте множество, но у меня со "стартманями" проблема, да и все равно я буду писать свою максимально простую обработку под свои нехитрые задачи.
Я потратила целый день, на то, чтобы программно получить печатную форму счета с помощью БСП. Благодаря статье на другом ресурсе у меня все получилось, правда, пришлось потратить еще полдня, чтобы к счету приделать подпись и печать. Поэтому хочу поделиться результатом и, возможно, облегчить кому-то жизнь.
Обработка нужна была, чтобы ежемесячно выгружать счета и акты из программы 1С:Бухгалтерия 3.0 в папку на диске в формате pdf. Счет должен быть с печатью и подписью. Некоторые счета нужно сразу отправлять клиенту по электронной почте, для этого в справочник Договоры контрагентов был добавлен дополнительный реквизит "Рассылка счетов" - в значении Истина счет включается в рассылку.
Ключевая функция обработки - получение табличного документа печатной формы:
ПечатныеФормы = УправлениеПечатью.СформироватьПечатныеФормы(ИмяМенеджераПечати, ИменаМакетов, МассивОбъектов,
ПараметрыПечати, ДопустимыеТипыОбъектовПечати);
Для добавления Подписи и печати:
УправлениеПечатьюБП.ДобавитьФаксимилеВФоне(ТбДок,ДокументСсылка);
&НаСервере
//По ссылке на документ получаем табличный документ печатной формы документа
функция СформироватьПечатнуюФорму(ДокументСсылка)
МассивОбъектов = Новый Массив();
МассивОбъектов.Добавить(ДокументСсылка);
ПараметрыПечати = Новый Структура();
ДопустимыеТипыОбъектовПечати = Неопределено;
Если ТипЗнч(ДокументСсылка) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
ИмяМенеджераПечати = "Обработка.ПечатьСчетаНаОплату";
ИменаМакетов = "СчетЗаказ";
Иначе
ИмяМенеджераПечати = "Документ.РеализацияТоваровУслуг";
ИменаМакетов = "Акт";
КонецЕсли;
// Получение табличного документа печатной формы документа
ПечатныеФормы = УправлениеПечатью.СформироватьПечатныеФормы(ИмяМенеджераПечати, ИменаМакетов,
МассивОбъектов,ПараметрыПечати, ДопустимыеТипыОбъектовПечати);
ТбДок =ПечатныеФормы.КоллекцияПечатныхФорм[0].ТабличныйДокумент;
Если ТипЗнч(ДокументСсылка) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
//Добавление печати и подписи в табличный документ
УправлениеПечатьюБП.ДобавитьФаксимилеВФоне(ТбДок,ДокументСсылка);
КонецЕсли;
Возврат ТБДок;
КонецФункции
В функцию вставлена проверка на тип документа, так как подпись и печать нужно вставлять только в счет.
Получив табличный документ, мы можем делать с ним все что угодно:
- сохранять на диск
&НаКлиенте
Процедура ВыгрузитьВPDF(Команда) //Сохраняем счета в папку на диске
Если не Объект.ПапкаДляЗаписи="" Тогда
ИмяКаталога = Объект.ПапкаДляЗаписи+"\Счета\"+Формат(Объект.Период.ДатаНачала,"ДФ='ММММ гггг'");
ПроверитьСоздатьКаталог(ИмяКаталога);
Для каждого документ из Объект.Счета Цикл
ТБДОк =СформироватьПечатнуюФорму(Документ.Ссылка);
ИмяФайла = ИмяКаталога+"\"+Документ.Контрагент+" счет на оплату от "+Формат(Документ.Дата,"ДФ=dd.MM.yyyy")+".pdf";
ТбДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);
Сообщить(ИмяКаталога+"\"+Документ.Контрагент+" счет на оплату от "+Формат(Документ.Дата,"ДФ=dd.MM.yyyy")+".pdf - записан");
КонецЦикла;
Иначе Сообщить("Не заполнен каталог для записи!");
КонецЕсли;
КонецПроцедуры
- отправлять по электронной почте (функция полностью была взята из статьи по БСП на другом ресурсе)
&НаСервере
Функция ОтправитьТабличныйДокументЭлектроннойПочтойКакPDF(УчетнаяЗаписьПочтыОтправителя, ПочтаПолучателя,
ТекстПисьма, ТемаПисьма,ТабДок)
Отправлено = Ложь;
Если УчетнаяЗаписьПочтыОтправителя = Неопределено Или УчетнаяЗаписьПочтыОтправителя.Пустая() Тогда
Возврат Отправлено;
КонецЕсли;
ПотокФайла = Новый ПотокВПамяти();
ТабДок.Записать(ПотокФайла, ТипФайлаТабличногоДокумента.PDF);
ДвоичныеДанныеФайла = ПотокФайла.ЗакрытьИПолучитьДвоичныеДанные();
ВременноеХранилищеФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла, Новый УникальныйИдентификатор);
Вложения = Новый Массив;
ОписаниеВложения = Новый Структура("Представление, АдресВоВременномХранилище", ТемаПисьма + ".pdf", ВременноеХранилищеФайла);
Вложения.Добавить(ОписаниеВложения);
ПараметрыПисьма = Новый Структура;
ПараметрыПисьма.Вставить("Кому", ПочтаПолучателя);
ПараметрыПисьма.Вставить("Тема", ТемаПисьма);
ПараметрыПисьма.Вставить("Тело", ТекстПисьма);
ПараметрыПисьма.Вставить("ТипТекста", "ПростойТекст");
ПараметрыПисьма.Вставить("Вложения", Вложения);
Попытка
Идентификатор = РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(УчетнаяЗаписьПочтыОтправителя, ПараметрыПисьма);
Если ЗначениеЗаполнено(Идентификатор) Тогда
Отправлено = Истина;
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации("Отправка письма " + ПочтаПолучателя, УровеньЖурналаРегистрации.Ошибка,,,ОписаниеОшибки());
КонецПопытки;
Возврат Отправлено;
КонецФункции
Листинг всей обработки :
&НаСервере
//По ссылке на документ получаем табличный документ печатной формы документа
функция СформироватьПечатнуюФорму(ДокументСсылка)
МассивОбъектов = Новый Массив();
МассивОбъектов.Добавить(ДокументСсылка);
ПараметрыПечати = Новый Структура();
ДопустимыеТипыОбъектовПечати = Неопределено;
Если ТипЗнч(ДокументСсылка) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
ИмяМенеджераПечати = "Обработка.ПечатьСчетаНаОплату";
ИменаМакетов = "СчетЗаказ";
Иначе
ИмяМенеджераПечати = "Документ.РеализацияТоваровУслуг";
ИменаМакетов = "Акт";
КонецЕсли;
// Получение табличного документа печатной формы документа
ПечатныеФормы = УправлениеПечатью.СформироватьПечатныеФормы(ИмяМенеджераПечати, ИменаМакетов, МассивОбъектов,
ПараметрыПечати, ДопустимыеТипыОбъектовПечати);
ТбДок =ПечатныеФормы.КоллекцияПечатныхФорм[0].ТабличныйДокумент;
Если ТипЗнч(ДокументСсылка) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
//Добавление печати и подписи в табличный документ
УправлениеПечатьюБП.ДобавитьФаксимилеВФоне(ТбДок,ДокументСсылка);
КонецЕсли;
Возврат ТБДок;
КонецФункции
&НаСервере
Функция ОтправитьТабличныйДокументЭлектроннойПочтойКакPDF(УчетнаяЗаписьПочтыОтправителя, ПочтаПолучателя,
ТекстПисьма, ТемаПисьма,ТабДок)
Отправлено = Ложь;
Если УчетнаяЗаписьПочтыОтправителя = Неопределено Или УчетнаяЗаписьПочтыОтправителя.Пустая() Тогда
Возврат Отправлено;
КонецЕсли;
ПотокФайла = Новый ПотокВПамяти();
ТабДок.Записать(ПотокФайла, ТипФайлаТабличногоДокумента.PDF);
ДвоичныеДанныеФайла = ПотокФайла.ЗакрытьИПолучитьДвоичныеДанные();
ВременноеХранилищеФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла, Новый УникальныйИдентификатор);
Вложения = Новый Массив;
ОписаниеВложения = Новый Структура("Представление, АдресВоВременномХранилище", ТемаПисьма + ".pdf", ВременноеХранилищеФайла);
Вложения.Добавить(ОписаниеВложения);
ПараметрыПисьма = Новый Структура;
ПараметрыПисьма.Вставить("Кому", ПочтаПолучателя);
ПараметрыПисьма.Вставить("Тема", ТемаПисьма);
ПараметрыПисьма.Вставить("Тело", ТекстПисьма);
ПараметрыПисьма.Вставить("ТипТекста", "ПростойТекст");
ПараметрыПисьма.Вставить("Вложения", Вложения);
Попытка
Идентификатор = РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(УчетнаяЗаписьПочтыОтправителя, ПараметрыПисьма);
Если ЗначениеЗаполнено(Идентификатор) Тогда
Отправлено = Истина;
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации("Отправка письма " + ПочтаПолучателя, УровеньЖурналаРегистрации.Ошибка,,,ОписаниеОшибки());
Сообщить("Во время отправки письма для "+ПочтаПолучателя+" произошла ошибка");
КонецПопытки;
Возврат Отправлено;
КонецФункции
&НаКлиенте
Процедура Отправить(Команда) //Отправить счета на электронную почту
Если ЗначениеЗаполнено(Объект.УчетнаяЗаписьЭП) Тогда
ТекстПисьма = "Уважаемый клиент, направляем Вам счет на оплату."+Символы.ПС+Символы.ПС+Символы.ПС+"С уважением, ООО КИЦРП";
Для каждого документ из Объект.Счета Цикл
Если не Документ.Email ="" и Документ.Рассылка Тогда
ТабДок = СформироватьПечатнуюФорму(Документ.Ссылка);
ТемаПисьма = "Счет для "+Документ.Контрагент+" от "+Формат(Документ.Дата,"ДФ=dd.MM.yyyy");
Отправлено = ОтправитьТабличныйДокументЭлектроннойПочтойКакPDF(Объект.УчетнаяЗаписьЭП, Документ.Email,ТекстПисьма, ТемаПисьма, ТабДок);
Если Отправлено Тогда Сообщить("Счет для "+Документ.Контрагент+" - отправлен."); КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
Сообщить("Не заполнена учетная запись!");
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
КонецПроцедуры
&НаКлиенте
Процедура ПапкаДляЗаписиНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
Диалог.Заголовок = "Выберите путь к папке для сохранения документов:";
Если Диалог. Выбрать() Тогда
Объект.ПапкаДляЗаписи=Диалог.Каталог;
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьСчетаНаСервере()
Дата1 = Объект.Период.ДатаНачала;
Дата2 = Объект.Период.ДатаОкончания;
ВидКонтактнойИнформации = Справочники.ВидыКонтактнойИнформации.EmailКонтрагенты;
Рассылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Рассылка счетов");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КонтрагентыКонтактнаяИнформация.Ссылка КАК Ссылка,
| КонтрагентыКонтактнаяИнформация.Представление КАК Представление
|ПОМЕСТИТЬ Контакты
|ИЗ
| Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКонтактнаяИнформация
|ГДЕ
| КонтрагентыКонтактнаяИнформация.Вид = &Вид
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ДоговорыКонтрагентовДополнительныеРеквизиты.Ссылка КАК Ссылка,
| ДоговорыКонтрагентовДополнительныеРеквизиты.Значение КАК Значение
|ПОМЕСТИТЬ Рассылка
|ИЗ
| Справочник.ДоговорыКонтрагентов.ДополнительныеРеквизиты КАК ДоговорыКонтрагентовДополнительныеРеквизиты
|ГДЕ
| ДоговорыКонтрагентовДополнительныеРеквизиты.Свойство = &Свойство
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| СчетНаОплатуПокупателю.Ссылка КАК Ссылка,
| СчетНаОплатуПокупателю.Дата КАК Дата,
| СчетНаОплатуПокупателю.Контрагент КАК Контрагент,
| Контакты.Представление КАК Email,
| Рассылка.Значение КАК Рассылка
|ИЗ
| Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю
| ЛЕВОЕ СОЕДИНЕНИЕ Контакты КАК Контакты
| ПО СчетНаОплатуПокупателю.Контрагент = Контакты.Ссылка
| ЛЕВОЕ СОЕДИНЕНИЕ Рассылка КАК Рассылка
| ПО СчетНаОплатуПокупателю.ДоговорКонтрагента = Рассылка.Ссылка
|ГДЕ
| СчетНаОплатуПокупателю.Дата МЕЖДУ &Дата1 И &Дата2
| И СчетНаОплатуПокупателю.Проведен = &Проведен
| И СчетНаОплатуПокупателю.ПометкаУдаления = &ПометкаУдаления";
Запрос.УстановитьПараметр("Вид", ВидКонтактнойИнформации);
Запрос.УстановитьПараметр("Дата1", Дата1);
Запрос.УстановитьПараметр("Дата2", Дата2);
Запрос.УстановитьПараметр("Свойство", Рассылка);
Запрос.УстановитьПараметр("Проведен", истина);
Запрос.УстановитьПараметр("ПометкаУдаления", ложь);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.ВЫбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Заполнитьзначениясвойств(Объект.Счета.Добавить(),ВыборкаДетальныеЗаписи);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьСчета(Команда)
Объект.Счета.Очистить();
ЗаполнитьСчетаНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСоздатьКаталог(ИмяКаталога)
КаталогНаДиске = Новый Файл(ИмяКаталога);
Если не КаталогНаДиске.Существует() Тогда
СоздатьКаталог(ИмяКаталога);
КонецЕсли;
//Ответ = Вопрос("Указанный каталог не существует. Создать каталог?", РежимДиалогаВопрос.ОКОтмена);
//Если Ответ = КодВозвратаДиалога.ОК Тогда
КонецПроцедуры
&НаКлиенте
Процедура ВыгрузитьВPDF(Команда) //Сохраняем счета в папку на диске
Если не Объект.ПапкаДляЗаписи="" Тогда
ИмяКаталога = Объект.ПапкаДляЗаписи+"\Счета\"+Формат(Объект.Период.ДатаНачала,"ДФ='ММММ гггг'");
ПроверитьСоздатьКаталог(ИмяКаталога);
Для каждого документ из Объект.Счета Цикл
ТБДОк =СформироватьПечатнуюФорму(Документ.Ссылка);
ИмяФайла = ИмяКаталога+"\"+Документ.Контрагент+" счет на оплату от "+Формат(Документ.Дата,"ДФ=dd.MM.yyyy")+".pdf";
ТбДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);
Сообщить(ИмяКаталога+"\"+Документ.Контрагент+" счет на оплату от "+Формат(Документ.Дата,"ДФ=dd.MM.yyyy")+".pdf - записан");
КонецЦикла;
Иначе Сообщить("Не заполнен каталог для записи!");
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьАктыНаСервере()
Дата1 = Объект.Период.ДатаНачала;
Дата2 = Объект.Период.ДатаОкончания;
ВидКонтактнойИнформации = Справочники.ВидыКонтактнойИнформации.EmailКонтрагенты;
Видоперации = Перечисления.ВидыОперацийРеализацияТоваров.Услуги;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КонтрагентыКонтактнаяИнформация.Ссылка КАК Ссылка,
| КонтрагентыКонтактнаяИнформация.Представление КАК Представление
|ПОМЕСТИТЬ Контакты
|ИЗ
| Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКонтактнаяИнформация
|ГДЕ
| КонтрагентыКонтактнаяИнформация.Вид = &Вид
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Контакты.Представление КАК Email,
| РеализацияТоваровУслуг.Ссылка КАК Ссылка,
| РеализацияТоваровУслуг.Контрагент КАК Контрагент,
| РеализацияТоваровУслуг.Дата КАК Дата
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
| ЛЕВОЕ СОЕДИНЕНИЕ Контакты КАК Контакты
| ПО РеализацияТоваровУслуг.Контрагент = Контакты.Ссылка
|ГДЕ
| РеализацияТоваровУслуг.Дата МЕЖДУ &Дата1 И &Дата2
| И РеализацияТоваровУслуг.ВидОперации = &ВидОперации";
Запрос.УстановитьПараметр("Вид", ВидКонтактнойИнформации);
Запрос.УстановитьПараметр("Дата1", Дата1);
Запрос.УстановитьПараметр("Дата2", Дата2);
Запрос.УстановитьПараметр("Проведен", истина);
Запрос.УстановитьПараметр("ПометкаУдаления", ложь);
Запрос.УстановитьПараметр("ВидОперации", ВидОперации);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Заполнитьзначениясвойств(Объект.Акты.Добавить(),ВыборкаДетальныеЗаписи);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьАкты(Команда)
Объект.Акты.Очистить();
ЗаполнитьАктыНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура ВыгрузитьВPDFАкты(Команда)//Сохраняем акты в папку на диске
Если не Объект.ПапкаДляЗаписи="" Тогда
ИмяКаталога = Объект.ПапкаДляЗаписи+"\Акты\"+Формат(Объект.Период.ДатаНачала,"ДФ='ММММ гггг'");
ПроверитьСоздатьКаталог(ИмяКаталога);
Для каждого документ из Объект.Акты Цикл
ТБДОк =СформироватьПечатнуюФорму(Документ.Ссылка);
ИмяФайла = ИмяКаталога+"\"+Документ.Контрагент+" акт от "+Формат(Документ.Дата,"ДФ=dd.MM.yyyy")+".pdf";
ТбДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);
Сообщить(ИмяКаталога+"\"+Документ.Контрагент+" акт от "+Формат(Документ.Дата,"ДФ=dd.MM.yyyy")+".pdf - записан");
КонецЦикла;
Иначе Сообщить("Не заполнен каталог для записи!");
КонецЕсли;
КонецПроцедуры
Саму обработку тоже прилагаю на всякий случай, но она, что называется, техническая, так как создавалась для отладки необходимых процедур и к тому же, если тратить стартмани, то на что-то более навороченное (на Инфостарте, как я уже писала, их много, а эта публикация для тех, у кого стартманей нет).
Обработка запускается через : "Файл" - "Открыть".
Подразумевается, что счета и акты уже созданы в программе их нужно только отправить.
В соответствующих полях нужно заполнить период документов для записи или отправки, путь к каталогу, в который будут сохранятся счета и учетную запись для электронной почты , которая тоже уже должна быть создана.
Печать и факсимиле должны быть подгружены в справочнике "Организации", т.е. когда вручную формируется печатная форма и стоит галочка "Подпись и печать", то в документе отображаются подпись и печать.
Далее на закладке "Счета" или "Акты" нажимаем кнопку "Заполнить". В таблице заполняются документы за выбранный период, электронная почта указанная в справочнике "Контрагенты" и галочка в поле "Рассылка", если в справочнике "Договоры" заполнен дополнительный реквизит "Рассылка счетов". Если такого реквизита нет, то галочки можно проставить в таблице.
Кнопка "Выгрузить счета в PDF" сохранит счета в указанную папку, а кнопка "Отправить по электронной почте" запустит рассылку тех счетов у которых заполнена электронная почта и стоит галочка в поле "Рассылка".
На закладке Акты кнопка "Отправить по электронной почте" отсутствует, так как в этом нет необходимости.
Обработка тестировалась на платформе 1С:Предприятие 8.3 (8.3.18.1741), релиз 1С:Бухгалтерия 3.0 (3.0.105.14) и (3.0.111.25).
&НаСервере
//По ссылке на документ получаем табличный документ печатной формы документа
функция СформироватьПечатнуюФорму(ДокументСсылка)
МассивОбъектов = Новый Массив();
МассивОбъектов.Добавить(ДокументСсылка);
ПараметрыПечати = Новый Структура();
ДопустимыеТипыОбъектовПечати = Неопределено;
Если ТипЗнч(ДокументСсылка) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
ИмяМенеджераПечати = "Обработка.ПечатьСчетаНаОплату";
ИменаМакетов = "СчетЗаказ";
Иначе
ИмяМенеджераПечати = "Документ.РеализацияТоваровУслуг";
ИменаМакетов = "Акт";
КонецЕсли;
// Получение табличного документа печатной формы документа
ПечатныеФормы = УправлениеПечатью.СформироватьПечатныеФормы(ИмяМенеджераПечати, ИменаМакетов, МассивОбъектов,
ПараметрыПечати, ДопустимыеТипыОбъектовПечати);
ТбДок =ПечатныеФормы.КоллекцияПечатныхФорм[0].ТабличныйДокумент;
Если ТипЗнч(ДокументСсылка) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
//Добавление печати и подписи в табличный документ
УправлениеПечатьюБП.ДобавитьФаксимилеВФоне(ТбДок,ДокументСсылка);
КонецЕсли;
Возврат ТБДок;
КонецФункции
Чтобы добавить дополнительный реквизит в справочник "Договоры", нужно по кнопке "Еще" в карточке договора выбрать пункт меню "Изменить состав дополнительных реквизитов", затем "Добавить" и создать реквизит с Наименованием "Рассылка счетов" (по этому названию ищется дополнительный реквизит для условия отбора в запросе) с типом "Булево"