Не редко возникает необходимость загрузить в справочники или документы 1С данные из текстового файла. Приведенный пример внешней обработки позволит преобразовать текстовый файл с известным разделителем данных в поле табличного документа для последующей обработки уже внутри 1С:Предприятия. Обработка содержит функцию разбора строки на массив данных, настраиваемый разделитель строки текста на "столбцы", процедуру чтения данных из текстового файла.
Разбор строки в массив с использованием функций из конфигурации 1С
Для разложения строки в массив в конфигурация 1С:Бухгалтерия, 1С:Торговля и 1С:УПП имеется замечательная функция - Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт. Функция "расщепляет" строку на подстроки, используя заданный разделитель. Разделитель может иметь любую длину. Если в качестве разделителя задан пробел, рядом стоящие пробелы считаются одним разделителем, а ведущие и хвостовые пробелы параметра "Стр" игнорируются. Подробнее можно прочесть внутри конфигурации - "Общие модули" -> "Общего назначения". Функция возвращает массив значений, элементы которого - подстроки.
Чтение текстового файла (txt) в 1С
Операцию импорта - экспорта текстовых файлов (формат тхт или csv, а также htm, html) очень удобно реализовать при помощи конструкции следующего вида:
1. Функция ПолучитьПотокЧтенияСтрок(Файл) - Назначение: Проверить наличие файла (функция Файл()), Создать текстовый документ (Новый ТекстовыйДокумент()), вызвать метод "Прочитать" для открытия потока чтения файла. Возвращает поток, готовый для чтения.
2. Процедура ЧтениеТХТФайла(Элемент) - Назначение: В цикле произвести последовательное чтение строк файла текстового документа, разбирая на массив колонок данных и добавляя значения массива в табличное поле;
Исходный код 1С функции создания текстового потока чтения файла ТХТ:
Код 1C v 8.х Функция ПолучитьПотокЧтенияСтрок(Файл)
Попытка
// Используется для доступа к параметрам файлов или каталогов.
ТекстовыйФайл = Новый Файл(Файл);
Если ТекстовыйФайл.Существует() = Ложь Тогда
Сообщить("Файла "+Файл+" не существует!");
Возврат Неопределено;
КонецЕсли;
// Текстовый документ предназначен для работы с текстами.
// Объект позволяет получать и сохранять текст в файле,
// работать со строками
ПотокЧтенияСтрок = Новый ТекстовыйДокумент();
ПотокЧтенияСтрок.Прочитать(ТекстовыйФайл);
Исключение
Сообщить("Файл не прочитан.", СтатусСообщения.Внимание);
Сообщить(ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
// Возвращает текст, извлеченный из файла
Возврат ПотокЧтенияСтрок;
КонецФункции // ПолучитьПотокЧтенияСтрок
// Исходный код функции загрузки строк в табличное поле:
Процедура ЧтениеТХТФайла(Элемент)
// Проверка на наличие имени файла
Если ПустаяСтрока(ИмяФайла) Тогда
Предупреждение("Для запуска обработки необходимо предварительно выбрать файл данных.");
Возврат;
КонецЕсли;
// Открыть файл, создать текстовый документ, прочитать
ПотокСтрок = ПолучитьПотокЧтенияСтрок(ИмяФайла);
// Очистить предыдущие значения
ТаблицаДокумента.Очистить();
ТаблицаДокумента.Колонки.Очистить();
// Создать колонки табличного документа
ТаблицаДокумента.Колонки.Добавить("Номер",,"Номер",5);
ТаблицаДокумента.Колонки.Добавить("Артикул",,"Артикул",11);
ТаблицаДокумента.Колонки.Добавить("Номенклатура",,"Номенклатура",25);
ТаблицаДокумента.Колонки.Добавить("Цена",,"Цена",6);
// Последовательное чтение строк текстового файла
КоличествоСтрок = ПотокСтрок.КоличествоСтрок();
Для Строка = 1 По КоличествоСтрок Цикл
// Обработка нажатия Ctrl + Break
ОбработкаПрерыванияПользователя();
// Чтение строки из файла тхт / csv
СтрокаИзФайла = ПотокСтрок.ПолучитьСтроку(Строка);
// Разбор строки в массив, используя в качествен символа-разделителя "|"
МассивСтрок = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(СтрокаИзФайла,"|");
// Добавить данные в табличную часть экранной формы
Стр=ТаблицаДокумента.Добавить();
Стр.Номер = Строка;
Стр.Артикул = МассивСтрок[0];
Стр.Номенклатура = МассивСтрок[1];
Стр.Цена = МассивСтрок[2];
// Отобразить информацию о ходе выполнения обработки
Состояние("Обработка строки файла : "
+ "строка " + Строка + " из " + КоличествоСтрок);
КонецЦикла;
// Отобразить результаты загрузки в форме элемента
ЭлементыФормы.ТаблицаДокумента.Значение = ТаблицаДокумента;
ЭлементыФормы.ТаблицаДокумента.СоздатьКолонки();
КонецПроцедуры // ЧтениеTXTФайла(Элемент)
В данном примере была произведена загрузка из текстового файла в следующем формате:
Код 7754|Процессор Atom 1.7|10,00
5054|Процессор AMD x64|8,99
7546|Мышь Microsoft|45,88
Код 1C v 8.2 УП //Процедура проверяет наличие в ТЧ дублей строк по указанным реквизитам
//ДокументСсылка - ссылка на проверяемый документ
//ИмяТабЧасти - имя проверяемой табличной части (строка)
//ПроверяемыеРеквизиты - перечень проверяемых реквизитов (строка, реквизиты разделяются запятой)
Процедура ПроверимДублиСтрок(ДокументСсылка,ИмяТабЧасти,ПроверяемыеРеквизиты,Отказ)
ТаблицаДокумента = ДокументСсылка[ИмяТабЧасти].Выгрузить();
ТаблицаДокумента.Колонки.Добавить("КвоПроверкаДублей");
ТаблицаДокумента.ЗаполнитьЗначения(1, "КвоПроверкаДублей");
ТаблицаДокумента.Свернуть(ПроверяемыеРеквизиты,"КвоПроверкаДублей");
Для Каждого ТекущаяСтрока Из ТаблицаДокумента Цикл
Если ТекущаяСтрока.КвоПроверкаДублей > 1 Тогда
РеквизитыДляСообщения = "";
Стр = СокрЛП(ПроверяемыеРеквизиты);
Пока Найти(Стр,",") > 0 Цикл
НаимРеквизита = СокрЛП(Лев(Стр,Найти(Стр,",") - 1));
Стр = Прав(Стр,СтрДлина(Стр) - Найти(Стр,","));
РеквизитыДляСообщения = РеквизитыДляСообщения+ТекущаяСтрока[НаимРеквизита]+", ";
КонецЦикла;
РеквизитыДляСообщения = РеквизитыДляСообщения+ТекущаяСтрока[СокрЛП(Стр)];
Сообщить("Информация "+РеквизитыДляСообщения+" введена несколько раз в табличную часть, проведение невозможно!");
Отказ = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Пример обращения к процедуре проверки
Код 1C v 8.2 УП // Процедура - обработчик события ОбработкаПроверкиЗаполнения объекта.
//
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если Запасы.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ПроверимДублиСтрок(Ссылка, "Запасы", "Номенклатура, АлгоритмФормированияШК,Регион", Отказ);
КонецПроцедуры
Да, в списке реквизитов добавленные случайно пробелы игнорируются
Процедуру можно добавить в общий модуль и обращаться к ней из любого документа
Экспорт
Процедура ОсновныеДействияФормыЭкспорт(Кнопка) - выгружает из указанного справочника данные в режиме экспорта в файл в формате Microsoft Excel с указанным именем, используя преобразование данных к типу число и типу строка;
Код 1C v 8.х Процедура ОсновныеДействияФормыЭкспорт(Кнопка)
Попытка
Попытка
// Загрузка объекта Microsoft Excel
Состояние("Выгрузка данных из 1С в Microsoft Excel...");
ExcelПриложение = Новый COMОбъект("Excel.Application");
Исключение
Сообщить("Ошибка при запуске Microsoft Excel."
+ Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
// Создадим книгу, по умолчанию в ней уже есть листы
Книга = ExcelПриложение.WorkBooks.Add();
// Используем первый лист книги Excel
Лист = Книга.WorkSheets(1);
// Сформировать шапку документа в первой строке листа
Колонка = 1;
Для каждого стр из ТП цикл
Если стр.Выгружать Тогда
Лист.Cells(1, Колонка).Value = стр.НазваниеРеквизита;
Колонка = Колонка + 1;
КонецЕсли;
КонецЦикла;
// Выгрузить данные справочника
выборка = Справочники[ИмяСправочника].Выбрать();
СтрокаЛиста = 2;
Пока выборка.Следующий() Цикл
Колонка = 1;
Для каждого стр из ТП цикл
Если стр.Выгружать Тогда
Попытка
// Установить значение в строке и колонке
Если ТипЗнч(выборка[стр.НазваниеРеквизита])=Тип("Число") Тогда
// Установить формат для типа Число
Лист.Cells(СтрокаЛиста, Колонка).NumberFormat = "0,00";
Лист.Cells(СтрокаЛиста, Колонка).Value =
Формат(выборка[стр.НазваниеРеквизита],"ЧГ=0");
иначе
// Для всех других типов установим формат "Текстовый"
Лист.Cells(СтрокаЛиста, Колонка).NumberFormat = "@";
Лист.Cells(СтрокаЛиста, Колонка).Value =
Строка(выборка[стр.НазваниеРеквизита]);
КонецЕсли;
исключение
// в случае ошибки вывести номер строки и колонки
Сообщить("Ошибка установки значения для: " +
выборка[стр.НазваниеРеквизита]);
Сообщить("Стр: " +СтрокаЛиста+ " Кол: " +
Колонка+ " Рек: " + стр.НазваниеРеквизита);
КонецПопытки;
Колонка = Колонка + 1;
КонецЕсли;
КонецЦикла;
СтрокаЛиста = СтрокаЛиста + 1;
Состояние("Экспорт из 1С в Excel " + СтрокаЛиста);
КонецЦикла;
// Сохраним созданную книгу в файл xls
Книга.SaveAs(имяФайла);
// Обязательно закроем соединение с COM объектом для освобождения памяти
ExcelПриложение.Quit();
Сообщить("Файл выгружен успешно: " + имяФайла );
Исключение
// Обработка ошибок экспорта данных из 1С в Excel
Сообщить("Ошибка записи данных файла :" + имяФайла);
Сообщить(ОписаниеОшибки());
Попытка
ExcelПриложение.Quit();
Исключение
КонецПопытки;
КонецПопытки;
КонецПроцедуры
Импорт
Исходный код процедуры 1С для загрузки XLS файла:
Код 1C v 8.х Процедура ЧтениеXLSФайла(Элемент)
Если ПустаяСтрока(ИмяФайла) Тогда
Предупреждение("Для запуска обработки необходимо предварительно выбрать файл Microsoft Excel.");
Возврат;
КонецЕсли;
Попытка
// Загрузка Microsoft Excel
Состояние("Загрузка Microsoft Excel...");
ExcelПриложение = Новый COMОбъект("Excel.Application");
Исключение
Сообщить("Ошибка при загрузке Microsoft Excel." + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
Попытка
// Открытие файла Microsoft Excel
Состояние("Открытие файла Microsoft Excel...");
ExcelФайл = ExcelПриложение.WorkBooks.Open(ИмяФайла);
Исключение
Сообщить("Ошибка открытия файла Microsoft Excel." + ИмяФайла + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
Попытка
// Обработка файла Microsoft Excel
Состояние("Обработка файла Microsoft Excel...");
// Читаем данные первого листа книги
ExcelЛист = ExcelФайл.Sheets(1);
// Определить количество строк и колонок выбранного листа книги Excel
xlCellTypeLastCell = 11;
ExcelПоследняяСтрока = ExcelЛист.Cells.SpecialCells(xlCellTypeLastCell).Row;
ExcelПоследняяКолонка = ExcelЛист.Cells.SpecialCells(xlCellTypeLastCell).Column;
Исключение
Сообщить("Ошибка открытия листа №1 Microsoft Excel." + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание);
// Закрыть COM соединение для экономии памяти
ExcelПриложение.Quit();
КонецПопытки;
// Создание описателя типов для таблицы значений
КЧ = Новый КвалификаторыЧисла(15,2);
КС = Новый КвалификаторыСтроки(50);
Массив = Новый Массив;
Массив.Добавить(Тип("Строка"));
ОписаниеТиповС = Новый ОписаниеТипов(Массив, , КС);
Массив.Очистить();
Массив.Добавить(Тип("Число"));
ОписаниеТиповЧ = Новый ОписаниеТипов(Массив, , ,КЧ);
// Очистить предыдущие значения
ТаблицаДокумента.Очистить();
ТаблицаДокумента.Колонки.Очистить();
// Создать колонки табличного документа
ТаблицаДокумента.Колонки.Добавить("Номер",ОписаниеТиповС,"Номер",5);
ТаблицаДокумента.Колонки.Добавить("Артикул",ОписаниеТиповС,"Артикул",11);
ТаблицаДокумента.Колонки.Добавить("Описание",ОписаниеТиповС,"Описание",25);
ТаблицаДокумента.Колонки.Добавить("Цена",ОписаниеТиповЧ,"Цена",6);
// Последовательное чтение строк с выбранного листа
Для Строка = 1 По ExcelПоследняяСтрока Цикл
// Обработка нажатия Ctrl + Break
ОбработкаПрерыванияПользователя();
// Добавить данные в табличную часть экранной формы
Стр=ТаблицаДокумента.Добавить();
Стр.Номер = Строка;
Попытка
Стр.Артикул = ExcelЛист.Cells(Строка, 1).Value;
Стр.Описание = ExcelЛист.Cells(Строка, 2).Value;
Стр.Цена = ExcelЛист.Cells(Строка, 3).Value;
Исключение
// Не редко происходит ошибка конвертации отдельной ячейки документа
Сообщить("Ошибка чтения строки файла Microsoft Excel." + Строка + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
// Отобразить информацию о ходе выполнения обработки
Состояние("Обработка файла Microsoft Excel : "
+ "строка " + Строка + " из " + ExcelПоследняяСтрока);
КонецЦикла;
// Закрыть COM соединение для экономии памяти
ExcelПриложение.Quit();
// Отобразить результаты загрузки в форме элемента
ЭлементыФормы.ТаблицаДокумента.Значение = ТаблицаДокумента;
ЭлементыФормы.ТаблицаДокумента.СоздатьКолонки();
КонецПроцедуры // ЧтениеXLSФайла(Элемент)