В данной статье описан пример реализации загрузки данных накладных из PDF файлов для одного крупного Ритейла...
И так у Нас есть несколько файлов в формате pdf, которые нам необходимо загрузить в 1С.
Чтение PDF файлов из 1С
Первым дело я стал искать, как напрямую можно прочитать данные из 1С в PDF файлах - было найдено много информации и вариантов решений, но к сожалению большинство из них не правильно работали с кодировкой В результате банальный текст вида Красный стул превращался в страшную кракозябру.
Далее после долгих поисков был найден конвертер PDF в TXT - pdf2txt
Поддержка командной строки:
PDF2TXT <input PDF file> [output TXT file] [-logfile] [-open] [-space] [-html] [-format] [-silent] [-blankline] [-summary] [-zoom <num>] [-?] [-h]
<input PDF file> : Open an existing PDF file to convert.
[output TXT file] : Write to TEXT file, the default is same filename of input PDF file.
[-first <page number>]: Specify the first page number.
[-last <page number>]: Specify the last page number.
[-logfile] : Write log to "C:\pdf2txt.log" file.
[-open] : Auto open the text file after it be created.
[-space] : Auto insert spaces into text file.
[-html] : Output to a HTML file, not a text file.
[-format] : Keep the page layout in the generated TXT file.
[-silent] : Disable error and warning messages.
[-blankline] : Auto delete blank line in the generated TXT file.
[-summary] : Get PDF document summary.
[-zoom <num>] : Set zoom ratio, the range is from 50 to 200.
[-unicode] : Create UTF-8 encoding text file.
Примеры:
Код Batch File (DOS, CMD, BAT) C:\>PDF2TXT C:\input.pdf
C:\>PDF2TXT C:\input.pdf -unicode
C:\>PDF2TXT C:\input.pdf -first 10 -last 12
C:\>PDF2TXT C:\input.pdf C:\output.txt
C:\>PDF2TXT C:\input.pdf -open -silent -logfile -zoom 150
C:\>PDF2TXT C:\input.pdf C:\output.txt -open -silent
C:\>PDF2TXT C:\*.pdf
C:\>PDF2TXT C:\*.pdf C:\*.txt
C:\>PDF2TXT C:\test\*.pdf C:\test\*.txt
В архиве (Скачать Вы можете из статьи по ссылке ) заготовка 1С обработки для частного случая, если она Вам подойдет - Хорошо
Если же нет, то Мы можем для Вас быстро доработать загрузку PDF в 1С !
Код на 1С для конфигурации УТ 10.3:
Код 1C v 8.х Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт
МассивСтрок = Новый Массив();
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = СокрЛ(Сред(Стр,Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
ТекЗнч = СокрЛП(Лев(Стр,Поз-1));
Если ЗначениеЗаполнено(ТекЗнч) Тогда
МассивСтрок.Добавить(ТекЗнч);
КонецЕсли;
Стр = Сред(Стр,Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
КонецФункции
Процедура КнопкаВыполнитьНажатие(Кнопка)
//Ищем Файлы
тч.Очистить();
НайденныеФайлы = НайтиФайлы(ПутьКPDF,"*.pdf",ложь);
Для каждого стр Из НайденныеФайлы Цикл
Нстр = ТЧ.Добавить();
Нстр.ФайлPDF = стр.Имя;
КонецЦикла;
ЭтаФорма.Обновить();
//Преобразуем PDF в TXT
Для каждого стр Из ТЧ Цикл
Попытка
pdf = СокрЛП(ПутьКPDF+"\"+стр.ФайлPDF);
txt = СтрЗаменить(pdf,"pdf","txt");
Команд = ПутьКPDF2TXT+"\pdf2txt.exe "+pdf+" "+txt;
ЗапуститьПриложение(Команд,ПутьКPDF,Истина);
стр.ФайлTXT = txt;
Исключение
стр.ФайлTXT = "!!!_ОШИБКА";
КонецПопытки;
ЭлементыФормы.ТЧ.ТекущаяСтрока = стр;
ЭлементыФормы.ТЧ.ОбновитьСтроки(стр);
КонецЦикла;
мТекущийПользователь = глЗначениеПеременной("глТекущийПользователь");
мСкладПоУмолчанию = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОсновнойСклад");
мОсновноеПодразделение = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОсновноеПодразделение");
мОсновнаяВалютаВзаиморасчетов = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОсновнаяВалютаВзаиморасчетов");
мОсновноеВедениеВзаиморасчетовПоДоговорам = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОсновноеВедениеВзаиморасчетовПоДоговорам");
мВидНоменклатурыПоУмолчанию = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОсновнойВидНоменклатуры");
мОтражатьВРеглУчете = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОтражатьДокументыВУправленческомУчете");
мОтражатьВБухУчета = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОтражатьДокументыВБухгалтерскомУчете");
мОтражатьВНалУчете = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(мТекущийПользователь, "ОтражатьДокументыВНалоговомУчете");
//Создаем Документ
Для каждого стр Из ТЧ Цикл
Состояние("Загружаю: "+стр.ФайлTXT);
текдок=Новый ТекстовыйДокумент;
текдок.Прочитать(стр.ФайлTXT,"UTF-8");
ЗагрузкаТЧ=Ложь;
ДокВозвратТоваровОтПокупателя = Документы.ВозвратТоваровОтПокупателя.СоздатьДокумент();
ДокВозвратТоваровОтПокупателя.Ответственный = мТекущийПользователь;
ДокВозвратТоваровОтПокупателя.Дата = ОбщегоНазначения.ПолучитьРабочуюДату();
ДокВозвратТоваровОтПокупателя.УстановитьНовыйНомер();
ДокВозвратТоваровОтПокупателя.ВидПоступления = Перечисления.ВидыПоступленияТоваров.НаСклад;
ДокВозвратТоваровОтПокупателя.СкладОрдер = Склад;
ДокВозвратТоваровОтПокупателя.Подразделение = мОсновноеПодразделение;
ДокВозвратТоваровОтПокупателя.ВалютаДокумента = Справочники.Валюты.НайтиПоКоду("643");
ДокВозвратТоваровОтПокупателя.УчитыватьНДС = ИСТИНА;
ДокВозвратТоваровОтПокупателя.СуммаВключаетНДС = ИСТИНА;
Для Ном=1 по текдок.КоличествоСтрок() цикл
ТСтр = текдок.ПолучитьСтроку(Ном);
ТекСтр = СокрЛП(ТСтр);
Если Найти(ТекСтр, "Всего по накладной")>0 Тогда
ЗагрузкаТЧ=Ложь;
//делаем пересчеты сумм, количества мест и НДС по строкам
Для Каждого СтрокаТабличнойЧасти Из ДокВозвратТоваровОтПокупателя.Товары Цикл
ОбработкаТабличныхЧастей.РассчитатьКоличествоМестТабЧасти(СтрокаТабличнойЧасти, ДокВозвратТоваровОтПокупателя);
ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(СтрокаТабличнойЧасти, ДокВозвратТоваровОтПокупателя);
ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТабличнойЧасти, ДокВозвратТоваровОтПокупателя);
КонецЦикла;
Попытка
ДокВозвратТоваровОтПокупателя.Записать(РежимЗаписиДокумента.Проведение);
Исключение
ДокВозвратТоваровОтПокупателя.Записать(РежимЗаписиДокумента.Запись);
КонецПопытки;
стр.Документ = ДокВозвратТоваровОтПокупателя.Ссылка;
стр.Инфо = "Все ОК";
ЭлементыФормы.ТЧ.ТекущаяСтрока = стр;
ЭлементыФормы.ТЧ.ОбновитьСтроки(стр);
//ВСЕ
Прервать;
КонецЕсли;
Если ЗагрузкаТЧ Тогда
ТекСтр = СтрЗаменить(ТекСтр, "подложке ","подложке");
ТекСтр = СтрЗаменить(ТекСтр, " ","|");
СтрМ=РазложитьСтрокуВМассивПодстрок(ТекСтр,"|");
Если СтрМ.Количество()>2 Тогда
//Сообщить(СтрМ);
Попытка
НоваяСтрока = ДокВозвратТоваровОтПокупателя.Товары.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоКоду(СтрМ[2]);
//НоваяСтрока.ХарактеристикаНоменклатуры = СтрокаТаблицы.ХарактеристикаНоменклатуры;
//УстановитьСтавкуНДСВТабЧасти(НоваяСтрока, СтрокаТаблицы);
//ПроверитьНаличиеСерииНоменклатуры(НоваяСтрока, СтрокаТаблицы);
//УстановитьПризнакВеденияПоСериямНоменклатуры(НоваяСтрока);
НоваяСтрока.ЕдиницаИзмерения = НоваяСтрока.Номенклатура.БазоваяЕдиницаИзмерения;
НоваяСтрока.Коэффициент = 1;
НоваяСтрока.Количество = Число(СтрМ[6]);
НоваяСтрока.Цена = Число(СтрМ[7]);
НоваяСтрока.Сумма = Число(СтрМ[8]);
НоваяСтрока.СуммаНДС = Число(СтрМ[11]);
НоваяСтрока.Качество = Справочники.Качество.Новый;
Попытка
НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС["НДС"+Лев(СокрЛП(СтрМ[9]),2)];
Исключение
НоваяСтрока.СтавкаНДС = НоваяСтрока.Номенклатура.СтавкаНДС;
КонецПопытки;
Исключение
Сообщить("Не загружено: "+ТекСтр);
КонецПопытки;
Иначе
Продолжить;
КонецЕсли;
Иначе
// Возможно что-то будет
КонецЕсли;
//Сообщить(ТекСтр);
Если Найти(ТекСтр, "Товарная накладная")>0 Тогда
ТекСтр = СтрЗаменить(ТекСтр, " ","|");
СтрМ=РазложитьСтрокуВМассивПодстрок(ТекСтр,"|");
Если СтрМ.Количество()>1 Тогда
//Сообщить(СтрМ);
ДокВозвратТоваровОтПокупателя.НомерВходящегоДокументаЭлектронногоОбмена = СтрМ[1];
ТекДата = СтрМ[2];
ДокВозвратТоваровОтПокупателя.ДатаВходящегоДокументаЭлектронногоОбмена = Дата(Прав(ТекДата,4)+Сред(ТекДата,4,2)+Лев(ТекДата,2));
КонецЕсли;
КонецЕсли;
Если Найти(ТекСтр, "Грузополучатель:")>0 Тогда
//Сообщить(ТекСтр);
//Получим ИНН
ГдеИНН = Найти(ТекСтр, "ИНН");
Если ГдеИНН>0 Тогда
ГдеИННвр= лев(ТекСтр,ГдеИНН+15);
текИНН = Прав(гдеИННвр, СтрДлина(ГдеИННвр)-(ГдеИНН+3));
текИНН = СокрЛП(СтрЗаменить(текИНН,".","")); текИНН = СокрЛП(СтрЗаменить(текИНН,",",""));
ТекОрганизация = Справочники.Организации.НайтиПоРеквизиту("ИНН",текИНН);
Если ТекОрганизация=Справочники.Организации.ПустаяСсылка() Тогда
ДокВозвратТоваровОтПокупателя.Организация = Организация;
Иначе
ДокВозвратТоваровОтПокупателя.Организация = ТекОрганизация;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Найти(ТекСтр, "Поставщик:")>0 Тогда
//Сообщить(ТекСтр);
//Получим ИНН
ГдеИНН = Найти(ТекСтр, "ИНН");
Если ГдеИНН>0 Тогда
ГдеИННвр= лев(ТекСтр,ГдеИНН+15);
текИНН = Прав(гдеИННвр, СтрДлина(ГдеИННвр)-(ГдеИНН+3));
текИНН = СокрЛП(СтрЗаменить(текИНН,".","")); текИНН = СокрЛП(СтрЗаменить(текИНН,",",""));
ТекПоставщик = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН",текИНН);
ДокВозвратТоваровОтПокупателя.Контрагент = ТекПоставщик;
ДокВозвратТоваровОтПокупателя.ДоговорКонтрагента = ТекПоставщик.ОсновнойДоговорКонтрагента;
КонецЕсли;
КонецЕсли;
Если Найти(ТекСтр, "Плательщик:")>0 Тогда
//Сообщить(ТекСтр);
//Получим ИНН
ГдеИНН = Найти(ТекСтр, "ИНН");
Если ГдеИНН>0 Тогда
ГдеИННвр= лев(ТекСтр,ГдеИНН+15);
текИНН = Прав(гдеИННвр, СтрДлина(ГдеИННвр)-(ГдеИНН+3));
текИНН = СокрЛП(СтрЗаменить(текИНН,".","")); текИНН = СокрЛП(СтрЗаменить(текИНН,",",""));
ТекПлательщик = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН",текИНН);
КонецЕсли;
КонецЕсли;
Если текстр="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" Тогда
ЗагрузкаТЧ=Истина;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура ПутьКPDF2TXTОткрытие(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Режим = РежимДиалогаВыбораФайла.ВыборКаталога;
ДиалогОткрытия = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытия.Каталог = "";
ДиалогОткрытия.МножественныйВыбор = Ложь;
ДиалогОткрытия.Заголовок = "Выберите каталог с PDF2TXT";
Если ДиалогОткрытия.Выбрать() Тогда
ПутьКPDF2TXT = ДиалогОткрытия.Каталог;
ПутьКPDF = ДиалогОткрытия.Каталог;
КонецЕсли;
КонецПроцедуры
Процедура ПутьКPDFОткрытие(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Режим = РежимДиалогаВыбораФайла.ВыборКаталога;
ДиалогОткрытия = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытия.Каталог = "";
ДиалогОткрытия.МножественныйВыбор = Ложь;
ДиалогОткрытия.Заголовок = "Выберите каталог с PDF2TXT";
Если ДиалогОткрытия.Выбрать() Тогда
ПутьКPDF = ДиалогОткрытия.Каталог;
КонецЕсли;
КонецПроцедуры
Код 1C v 8.х //Пример кода
Перем Подключились;
Перем COMОбъект;
Функция ПолучитьНом(Выборка)
Ном = Справочники.Номенклатура.НайтиПоНаименованию(СокрЛП(Выборка.Номенклатура));
Если Ном.Пустая() Тогда
ВвестиЗначение(Ном, "Выберите номенклатуру " + СокрЛП(Выборка.Номенклатура), Тип("СправочникСсылка.Номенклатура"));
КонецЕсли;
Возврат Ном;
КонецФункции
Функция ПодключитьсяКCRM()
Подключились = Истина;
Попытка
Подкл = Новый COMОбъект("V82.COMConnector");
COMОбъект = Подкл.Connect("Srvr=""Server1"";Ref=""TradeUT"";Usr=""ObmenBot"";Pwd=""12345""");
Исключение
Сообщить(ОписаниеОшибки());
Подключились = Ложь;
КонецПопытки;
Возврат Подключились;
КонецФункции
Процедура Реализации_Анализ(Элемент)
Если не Подключились Тогда
Если не ПодключитьсяКCRM() Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Запрос = COMОбъект.NewObject("Запрос");
Запрос.Текст = ПолучитьМакет("ЗапросПродажи").ПолучитьТекст();
Запрос.УстановитьПараметр("Дата1", НачалоДня(ДатаНач));
Запрос.УстановитьПараметр("Дата2", КонецДня(ДатаКон));
глРезультатЗапросаПродажи = Запрос.Выполнить();
Выборка = глРезультатЗапросаПродажи.Выбрать(COMОбъект.ОбходРезультатаЗапроса.ПоГруппировкам);
ДокРеал = Документы.РеализацияТоваровУслуг;
СпрКонтр = Справочники.Контрагенты;
ТаблицаДокументов.Очистить();
Пока Выборка.Следующий() Цикл
ОбработкаПрерыванияПользователя();
Стр = ТаблицаДокументов.Добавить();
ЗаполнитьЗначенияСвойств(Стр, Выборка);
Стр.Документ = ДокРеал.НайтиПоНомеру(Стр.Номер, Стр.Дата);
Стр.ТекстКонтрагент = Выборка.КонтрагентНаименование + ", ИНН " + Выборка.ИННКонтрагента;
Если не ПустаяСтрока(Выборка.ИННКонтрагента) Тогда
ВыборкаКонтр = СпрКонтр.Выбрать(,, Новый Структура("ИНН", Выборка.ИННКонтрагента));
Пока ВыборкаКонтр.Следующий() Цикл
Если не ЗначениеЗаполнено(Стр.Контрагент) или ВыборкаКонтр.КПП = Выборка.КППКонтрагента Тогда
Стр.Контрагент = ВыборкаКонтр.Ссылка;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
ЭлементыФормы.кнЗагрузитьШаг1.Доступность = Истина;
ЭлементыФормы.ИндикаторРеал.МаксимальноеЗначение = ТаблицаДокументов.Количество();
КонецПроцедуры
Процедура Реализации_Загрузить(Элемент)
ЭлементыФормы.ИндикаторРеал.МаксимальноеЗначение = ТаблицаДокументов.Количество();
ЗначениеИндикатораРеал = 0;
ДокРеал = Документы.РеализацияТоваровУслуг;
ВыборкаДок = глРезультатЗапросаПродажи.Выбрать(COMОбъект.ОбходРезультатаЗапроса.ПоГруппировкам);
мСписокВидовДоговоров = Новый СписокЗначений;
мСписокВидовДоговоров.Добавить(Перечисления.ВидыДоговоровКонтрагентов.СПокупателем);
СпособЗаполненияЦен = Перечисления.СпособыЗаполненияЦен.ПоЦенамНоменклатуры;
Пока ВыборкаДок.Следующий() Цикл
ЗначениеИндикатораРеал = ЗначениеИндикатораРеал + 1;
СтрокаТаб = ТаблицаДокументов.Найти(ВыборкаДок.Номер, "Номер");
Если СтрокаТаб <> Неопределено Тогда
Если ЗначениеЗаполнено(СтрокаТаб.Документ) Тогда
Док = СтрокаТаб.Документ.ПолучитьОбъект();
Док.Товары.Очистить();
Док.Услуги.Очистить();
Иначе
Док = ДокРеал.СоздатьДокумент();
КонецЕсли;
Док.Дата = ВыборкаДок.Дата;
Док.Номер = ВыборкаДок.Номер;
Док.Контрагент = СтрокаТаб.Контрагент;
ЗаполнениеДокументов.ЗаполнитьШапкуДокумента(Док, глЗначениеПеременной("глТекущийПользователь"), Док.мВалютаРегламентированногоУчета, "Продажа");
ЗаполнениеДокументов.ПриИзмененииЗначенияКонтрагента(Док, мСписокВидовДоговоров);
ЗаполнениеДокументов.ПриИзмененииЗначенияДоговора(Док, Док.ВалютаДокумента, Док.мВалютаРегламентированногоУчета, СпособЗаполненияЦен, Ценообразование.ПолучитьСтруктуруРеквизитовДокументаДляЦенообразования(Док), "Продажа", "Товары", Неопределено);
Док.ЗаполнитьСчетаУчетаРасчетов();
Док.УчитыватьНДС = Ложь;
ВыборкаНом = ВыборкаДок.Выбрать(COMОбъект.ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаНом.Следующий() Цикл
ОбработкаПрерыванияПользователя();
Ном = ПолучитьНом(ВыборкаНом);
Если ВыборкаНом.Идентификатор = 1 Тогда
СтрокаТЧ = Док.Товары.Добавить();
СтрокаТЧ.Номенклатура = Ном;
Док.ЗаполнитьСчетаУчетаВСтрокеТабЧасти(СтрокаТЧ, "Товары", Истина);
Иначе
СтрокаТЧ = Док.Услуги.Добавить();
СтрокаТЧ.Номенклатура = Ном;
Док.ЗаполнитьСчетаУчетаВСтрокеТабЧастиУслуги(СтрокаТЧ, ИСТИНА);
ОбработкаТабличныхЧастей.ЗаполнитьСодержаниеТабЧасти(СтрокаТЧ, Док);
КонецЕсли;
ОбработкаТабличныхЧастей.ЗаполнитьСтавкуНДСТабЧасти(СтрокаТЧ, Док);
ОбработкаТабличныхЧастей.ЗаполнитьЕдиницуЦенуПродажиТабЧасти(СтрокаТЧ, Док, Док.мВалютаРегламентированногоУчета);
СтрокаТЧ.Количество = ВыборкаНом.Количество;
СтрокаТЧ.Сумма = ВыборкаНом.Сумма;
СтрокаТЧ.Цена = СтрокаТЧ.Сумма / ?(ВыборкаНом.Количество = 0, 1, ВыборкаНом.Количество);
КонецЦикла;
Если не ВыборкаДок.ДоставкаОтдельно и ВыборкаДок.СтоимостьДоставкиПлан <> 0 Тогда
СтрокаТЧ = Док.Товары.Добавить();
СтрокаТЧ.Номенклатура = Док.Товары[0].Номенклатура;
Док.ЗаполнитьСчетаУчетаВСтрокеТабЧасти(СтрокаТЧ, "Товары", Истина);
ОбработкаТабличныхЧастей.ЗаполнитьСтавкуНДСТабЧасти(СтрокаТЧ, Док);
ОбработкаТабличныхЧастей.ЗаполнитьЕдиницуЦенуПродажиТабЧасти(СтрокаТЧ, Док, Док.мВалютаРегламентированногоУчета);
СтрокаТЧ.Сумма = - ВыборкаДок.СтоимостьДоставкиПлан;
СтрокаТЧ = Док.Услуги.Добавить();
СтрокаТЧ.Номенклатура = Справочники.Номенклатура.ТранспортныеУслуги;
Док.ЗаполнитьСчетаУчетаВСтрокеТабЧастиУслуги(СтрокаТЧ, ИСТИНА);
ОбработкаТабличныхЧастей.ЗаполнитьСодержаниеТабЧасти(СтрокаТЧ, Док);
ОбработкаТабличныхЧастей.ЗаполнитьСтавкуНДСТабЧасти(СтрокаТЧ, Док);
ОбработкаТабличныхЧастей.ЗаполнитьЕдиницуЦенуПродажиТабЧасти(СтрокаТЧ, Док, Док.мВалютаРегламентированногоУчета);
СтрокаТЧ.Количество = 1;
СтрокаТЧ.Цена = ВыборкаДок.СтоимостьДоставкиПлан;
СтрокаТЧ.Сумма = ВыборкаДок.СтоимостьДоставкиПлан;
КонецЕсли;
Ош = Ложь;
Попытка
Док.Записать(?(Проводить, РежимЗаписиДокумента.Проведение, РежимЗаписиДокумента.Запись));
Ош = Истина;
Исключение
КонецПопытки;
Если Ош и Проводить Тогда
Док.Записать(РежимЗаписиДокумента.Запись);
КонецЕсли;
СтрокаТаб.Документ = Док.Ссылка;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Подключились = Ложь;
Гуляя по просторам интернета, случайно наткнулся на обработку HTML Редактор (Андрей Михайлов aka MAV):
Далее, пришла в голову интересная идея, сделать красивыми комментарии в документах ( у нас они очень большие и многострочные, в отдельной закладке), с поддержкой копирования информации из WORD и EXCEL, с сохранением всех цветов и стилей. Подредактировав данную обработку, стали доступны следующие функции:
1. Добавление текста
2. Добавление, просмотр и печать
3. Просмотр и печать
Теперь, более подробно:
Вот так выгляди поле комментариев в нашей базе:
1. Нажав на кнопку "Добавить комментарий" срабатывает Процедура ДобавитьКоммент(Элемент)
Код 1C v 8.х
Процедура ДобавитьКоммент(Элемент)
форм=обработки.HTML.ПолучитьФорму("Форма");
текст = форм.ОткрытьМодально();
если не Пустаястрока(текст) тогда
комментарий="Добавил: "+глтекущийпользователь +" , Добавлено: "+текущаядата()+текст+комментарий;
ЭлементыФормы.ПолеHTMLДокумента.УстановитьТекст(комментарий);
конецесли;
КонецПроцедуры
2. Процедура вызова "Добавление, просмотр и печать"
Код 1C v 8.х
Процедура ВставитьПланГрафик(Кнопка)
форм=обработки.HTML.ПолучитьФорму("ФормаПросмотра");
форм.текст=ПланГрафик;
текст=форм.ОткрытьМодально();
ПланГрафик=текст+ПланГрафик;
КонецПроцедуры
Откроется форма, вида:
Нажав на "Добавить запись" и вставив Таблицу из Excel:
Нажимаем Добавить и получаем:
3. Просмотр и печать
Код 1C v 8.х
Процедура ИсторияИзмененийПросмотр(Кнопка)
форм=обработки.HTML.ПолучитьФорму("Просмотр");
форм.текст=ИсторияИзменений;
форм.ОткрытьМодально();
КонецПроцедуры
Откроется форма просмотра реквизита ИсторияИзменений.
Обработка HTML редактор:
Для 8.0
Для 8.1 Код 1C v 8.х
// Функция возвращает Истина при соответствии типов, ложь в обратном случае
Функция НужныйТипЗнач(ИсхЗнач,ТипЗнач)
Возврат ТипЗнч(ИсхЗнач) = Тип(ТипЗнач);
КонецФункции
// Некоторые примеры обращения
// ИсхЗнач - проверяемое значение
// НужныйТипЗнач(ИсхЗнач,"Строка")
// НужныйТипЗнач(глЗначениеПеременной("глТекущийПользователь"),"СправочникСсылка.Пользователи")
// НужныйТипЗнач(ИсхЗнач,"Форма")
// НужныйТипЗнач(ИсхЗнач,"Булево")
// НужныйТипЗнач(ИсхЗнач,"Строка")
// НужныйТипЗнач(ИсхЗнач,"Число")
// НужныйТипЗнач(ИсхЗнач,"Дата"))
// НужныйТипЗнач(ИсхЗнач,"Массив")
// НужныйТипЗнач(ИсхЗнач,"Структура")
// НужныйТипЗнач(ИсхЗнач,"Соответствие")
// НужныйТипЗнач(ИсхЗнач,"СписокЗначений")
// НужныйТипЗнач(ИсхЗнач,"ТаблицаЗначений")
// НужныйТипЗнач(ИсхЗнач,"ДеревоЗначений")
// НужныйТипЗнач(ИсхЗнач,"ПланСчетовСсылка.Хозрасчетный")
// НужныйТипЗнач(ИсхЗнач,"ПланСчетовСсылка.Налоговый")
// НужныйТипЗнач(ИсхЗнач,"ХранилищеЗначения")
// НужныйТипЗнач(ИсхЗнач,"Картинка")
// НужныйТипЗнач(ИсхЗнач,"ПолеВвода")
// НужныйТипЗнач(ИсхЗнач,"Панель")
// НужныйТипЗнач(ИсхЗнач,"Флажок")
// НужныйТипЗнач(ИсхЗнач,"РегистрРасчетаНаборЗаписей.УправленческиеНачисления")
// НужныйТипЗнач(ИсхЗнач,"ПланВидовРасчетаСсылка.ОсновныеНачисленияОрганизаций")
// НужныйТипЗнач(ИсхЗнач,"ДокументСсылка.ОтпускПоУходуЗаРебенком")
// НужныйТипЗнач(ИсхЗнач,"ИнтернетПочтовоеСообщение")
// НужныйТипЗнач(ИсхЗнач, "БизнесПроцессСсылка.м_Документооборот")
Код 1C v 7.x
// Функция возвращает 1 при соответствии типов, 0 в обратном случае
Функция НужныйТипЗнач(ИсхЗнач,ТипЗнач)
Если ТипЗначенияСтр((ИсхЗнач) = ТипЗнач тогда
Возврат 1;
Иначе
Возврат 0;
КонецЕсли;
КонецФункции
// Некоторые примеры обращения
// ИсхЗнач - проверяемое значение
// НужныйТипЗнач(ИсхЗнач,"Строка")
// Значения типов данных:
// ''Число'' (''Number'') - числовой тип данных;
// ''Строка'' (''String'') - строковый тип данных;
// ''Дата'' (''Date'') - тип данных Дата;
// ''Перечисление'' (''Enum'') - агрегатный тип данных ''Перечисление'';
// ''Справочник'' (''Reference'') - агрегатный тип данных ''Справочник'';
// ''Документ'' (''Document'') - агрегатный тип данных ''Документ'';
// ''Регистр'' (''Register'') - агрегатный тип данных ''Регистр'';
// ''Календарь'' (''Calendar'') - агрегатный тип данных ''Календарь'';
// ''ВидРасчета'' (''Calculation'') - агрегатный тип данных ''ВидРасчета'';
// ''ЖурналРасчетов'' (''CalcJournal'') - агрегатный тип данных ''ЖурналРасчетов'';
// ''ПланСчетов'' (''ChartOfAccounts'') - агрегатный тип данных ''ПланСчетов'';
// ''Счет'' (''Account'') - агрегатный тип данных ''Счет'';
// ''Операция'' (''Operation'') - агрегатный тип данных ''Операция'';
// ''КорректныеПроводки'' (''CorrectEntries'') - агрегатный тип данных ''КорректныеПроводки'';
// ''БухгалтерскиеИтоги'' (''BookkeepingTotals'') - агрегатный тип данных ''БухгалтерскиеИтоги'';
// ''Таблица'' (''Table'') - агрегатный тип данных ''Таблица'';
// ''Текст'' (''Text'') - агрегатный тип данных ''Текст'';
// ''Запрос'' (''Query'') - агрегатный тип данных ''Запрос'';
// ''СписокЗначений'' (''ValueList'') - агрегатный тип данных ''СписокЗначений'';
// ''ТаблицаЗначений'' (''ValueTable'') - агрегатный тип данных ''ТаблицаЗначений'';
// ''Периодический'' (''Periodic'') - агрегатный тип данных ''Периодический'';
// ''Картинка'' (''Picture'') - агрегатный тип данных ''Картинка'';
// ''ГрупповойКонтекст'' (''GroupContext'') - контекст программного модуля или Формы;
// ''OLE'' (''OLE'') - OLE-объект.
// ''НеизвестныйОбьект'' (''UnknownObject'') - для типов, для которых в системе не предусмотрено специальное строковое обозначение;
// '''' (пустая строка) - неопределенный тип данных.
Для 8.2:
Открыть форму нового документа и предоставить пользователю самому интерактивно записать данные объекта в базу данных:
проще всего использовать метод глобального контекста ОткрытьФорму(). Это можно сделать на клиенте.
Код 1C v 8.2 УП ОткрытьФорму("Документ.ПриходнаяНакладная.ФормаОбъекта");
При этом создается новый документ и открывается для редактирования основная форма этого документа.
Если нужно какое-то предварительное заполнение документа начальными данными, то это можно сделать либо с помощью свойств реквизитов документа ЗначениеЗаполнения, ЗаполнятьИзДанныхЗаполнения либо в обработчике события документа ОбработкаЗаполнения.
Создать новый документ программно, программно заполнить его данными и программно записать. Затем, если нужно, показать его пользователю:
можно программно создать документ на сервере, заполнить данными, если это нужно в обработчике события ОбработкаЗаполнения, записать, и передать ссылку на новый документ в метод глобального контекста ОткрытьЗначение(), который откроет форму этого документа. Например:
Код 1C v 8.2 УП &НаКлиенте
Процедура ПриходнаяНакладная(Команда)
СсылкаНаДокумент = СоздатьНовыйДокумент();
ОткрытьЗначение(СсылкаНаДокумент);
КонецПроцедуры
&НаСервере
Функция СоздатьНовыйДокумент()
НовыйДокумент = Документы.ПриходнаяНакладная.СоздатьДокумент();
НовыйДокумент.Номер = "111";
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Записать();
Возврат НовыйДокумент.Ссылка;
КонецФункции
Подробнее об использовании методов ОткрытьЗначение() и ОткрытьФорму() можно прочитать в синтакс-помощнике: Глобальный контекст - Процедуры и функции для интерактивной работы
Код 1C v 8.2 УП // ЕЩЕ ПРИМЕР:
&НаКлиенте
Процедура СоздатьНовыйДокумент(Команда)
// Вставить содержимое обработчика.
Если СоздатьНовыйДокументНаСервере() = 0 Тогда
Сообщить("Не удалось создать новый документ");
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция СоздатьНовыйДокументНаСервере()
Перем НоваяРасходнаяНакладная;
Перем СтрокаТЧ;
НоваяРасходнаяНакладная=ДокРасходнаяНакладная.СоздатьДокумент();
//Заполняем реквизиты шапки
НоваяРасходнаяНакладная.Дата= ТекущаяДата();
НоваяРасходнаяНакладная.Фирма =Справочники.Фирмы.ОсновнаяФирма;
НоваяРасходнаяНакладная.Контрагент=Справочники.Контрагенты.НайтиПоКоду("000000001");
НоваяРасходнаяНакладная.Склад=Справочники.Склады.ОсновнойСклад;
//Заполняем табличную часть
СтрокаТЧ=НоваяРасходнаяНакладная.ТЧТовары.Добавить();
СтрокаТЧ.Товар=Справочники.Номенклатура.НайтиПоКоду("000000002");
СтрокаТЧ.Цена=СтрокаТЧ.Товар.РозничнаяЦена;
СтрокаТЧ.Количество= 2;
СтрокаТЧ.Сумма=СтрокаТЧ.Цена*СтрокаТЧ.Количество;
Попытка
НоваяРасходнаяНакладная.Записать();
Возврат 1;
Исключение
Возврат 0;
КонецПопытки;
КонецФункции
Для 8.1:
Код 1C v 8.х
//Создаем документ Выплата, Документ будет создан и показан пользователю, Но НЕ ЗАПИСАН
НовДок = Документы.ЗарплатаКВыплатеОрганизаций.ПолучитьФормуНовогоДокумента();
НовДок.Дата=ТекущаяДата();
НовДок.Организация=Организация;
НовДок.ПериодРегистрации=ПериодРегистрации;
НовДок.ответственный= глЗначениеПеременной("глТекущийПользователь");
НовДок.Комментарий="Выплата за "+МесяцСтрока;
НовДок.ЭлементыФормы.Комментарий.Доступность=Ложь;
Для Каждого ТекущаяСтрока Из ТаблицыЗначений Цикл // заполним табличную часть документа, из ТаблицыЗначений
НС=НовДок.зарплата.добавить();
нс.Авторасчет=истина;
нс.Физлицо = ТекущаяСтрока.Физлицо;
нс.ВыплаченностьЗарплаты=Перечисления.ВыплаченностьЗарплаты.НеВыплачено;
нс.сумма=ТекущаяСтрока.Результат;
КонецЦикла;
НовДок.Открыть();
//Для создания и записи документа используется следующий код:
НовДок = Документы.РасходнаяНакладная.СоздатьДокумент();
НовДок.Дата=ТекущаяДата();
НовыйДок.УстановитьНовыйНомер();
НовДок.Организация=Организация;
НовДок.ПериодРегистрации=ПериодРегистрации;
НовДок.ответственный= глЗначениеПеременной("глТекущийПользователь");
НовДок.Комментарий="Выплата за "+МесяцСтрока;
НовДок.ЭлементыФормы.Комментарий.Доступность=Ложь;
Для Каждого ТекущаяСтрока Из ТаблицыЗначений Цикл // заполним табличную часть документа, из ТаблицыЗначений
НС=НовДок.зарплата.добавить();
нс.Авторасчет=истина;
нс.Физлицо = ТекущаяСтрока.Физлицо;
нс.ВыплаченностьЗарплаты=Перечисления.ВыплаченностьЗарплаты.НеВыплачено;
нс.сумма=ТекущаяСтрока.Результат;
КонецЦикла;
НовДок.Записать();
//Или так:
НовыйДок = Документы.ПеремещениеТоваров.СоздатьДокумент();
НовыйДок.Дата = ПолеВводаДаты;
НовыйДок.УстановитьВремя();
НовыйДок.УстановитьНовыйНомер();
// Формирование табличной части
Для Н=1 По N Цикл
НоваяСтрока = НовыйДок.Товары.Добавить();
НоваяСтрока.Номенклатура = СтрокаДанных.Номенклатура;
// формируются другие реквизиты табличной части
КонецЦикла;
НовыйДок.Записать();
СписокДокументов.Добавить(НовыйДок.Ссылка);