Загрузка данных
// Форма «Загрузка артикулов» внешнего отчета «Остатки товаров по артикулам».
//
// Открывается из основной формы отчета, возвращает владельцу Массив из Строка —
// введенные артикулы. При отказе возвращает Неопределено.
//
// Артикулы вводятся в поле табличного документа, а не в таблицу формы: только так
// работает вставка колонки из буфера обмена (Ctrl+V) — таблица управляемой формы
// многострочную вставку не принимает. Строка 1 — шапка «Артикулы», данные с 2-й.
// Так же устроены типовые формы загрузки из внешних файлов, например
// ОбщаяФорма.ЗагрузкаИдентификаторовИзВнешнихФайлов.
#Область ОбработчикиСобытийФормы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ИнициализироватьТабличныйДокумент();
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура Готово(Команда)
СписокАртикулов = ВведенныеАртикулы();
Если СписокАртикулов.Количество() = 0 Тогда
ПоказатьПредупреждение(, НСтр("ru = 'Не введено ни одного артикула.'"));
Возврат;
КонецЕсли;
Закрыть(СписокАртикулов);
КонецПроцедуры
&НаКлиенте
Процедура ЗакрытьФорму(Команда)
Закрыть(Неопределено);
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьСписок(Команда)
ИнициализироватьТабличныйДокумент();
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьИзФайла(Команда)
Оповещение = Новый ОписаниеОповещения("ЗаполнитьИзФайлаЗавершение", ЭтотОбъект);
ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла();
ПараметрыЗагрузки.ИдентификаторФормы = УникальныйИдентификатор;
ПараметрыЗагрузки.Диалог.Заголовок = НСтр("ru = 'Выберите файл с артикулами'");
ПараметрыЗагрузки.Диалог.Фильтр = НСтр(
"ru = 'Все поддерживаемые форматы (*.xlsx;*.xls;*.ods;*.mxl;*.csv;*.txt)|*.xlsx;*.xls;*.ods;*.mxl;*.csv;*.txt'");
ФайловаяСистемаКлиент.ЗагрузитьФайл(Оповещение, ПараметрыЗагрузки);
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
// Обработчик выбора файла: дописывает артикулы из первой колонки файла в таблицу.
//
// Параметры:
// ПомещенныйФайл - Структура - см. ФайловаяСистемаКлиент.ЗагрузитьФайл
// - Неопределено - пользователь отказался от выбора.
// ДополнительныеПараметры - Произвольный - не используется.
//
&НаКлиенте
Процедура ЗаполнитьИзФайлаЗавершение(ПомещенныйФайл, ДополнительныеПараметры) Экспорт
Если ПомещенныйФайл = Неопределено Тогда
Возврат;
КонецЕсли;
Добавлено = ДобавитьАртикулыИзФайла(ПомещенныйФайл.Хранение, ПомещенныйФайл.Имя);
Если Добавлено = 0 Тогда
ПоказатьПредупреждение(, НСтр("ru = 'В первой колонке файла нет ни одного значения.'"));
КонецЕсли;
КонецПроцедуры
// Готовит пустой бланк: шапка «Артикулы» в первой строке, ниже — место для ввода.
//
&НаСервере
Процедура ИнициализироватьТабличныйДокумент()
ТаблицаАртикулов.Очистить();
Линия = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная);
Шапка = ТаблицаАртикулов.Область("R1C1");
Шапка.Текст = НСтр("ru = 'Артикулы'");
Шапка.Шрифт = Новый Шрифт(, , Истина);
Шапка.ЦветФона = Новый Цвет(240, 240, 240);
Шапка.Обвести(Линия, Линия, Линия, Линия);
Шапка.ШиринаКолонки = 40;
ТаблицаАртикулов.ФиксацияСверху = 1;
КонецПроцедуры
// Считывает непустые значения первой колонки, начиная со строки под шапкой.
//
// Возвращаемое значение:
// Массив из Строка
//
&НаСервере
Функция ВведенныеАртикулы()
Артикулы = Новый Массив;
Для НомерСтроки = 2 По ТаблицаАртикулов.ВысотаТаблицы Цикл
Артикул = СокрЛП(ТаблицаАртикулов.Область("R" + НомерСтроки + "C1").Текст);
Если Не ПустаяСтрока(Артикул) Тогда
Артикулы.Добавить(Артикул);
КонецЕсли;
КонецЦикла;
Возврат Артикулы;
КонецФункции
// Дописывает в таблицу артикулы из файла.
//
// Параметры:
// АдресФайла - Строка - адрес двоичных данных файла во временном хранилище.
// ИмяФайла - Строка - имя файла с расширением.
//
// Возвращаемое значение:
// Число - сколько значений добавлено.
//
&НаСервере
Функция ДобавитьАртикулыИзФайла(АдресФайла, ИмяФайла)
ИзФайла = АртикулыИзФайла(АдресФайла, ИмяФайла);
НомерСтроки = Макс(ТаблицаАртикулов.ВысотаТаблицы, 1);
Для Каждого Артикул Из ИзФайла Цикл
НомерСтроки = НомерСтроки + 1;
ТаблицаАртикулов.Область("R" + НомерСтроки + "C1").Текст = Артикул;
КонецЦикла;
Возврат ИзФайла.Количество();
КонецФункции
// Разбирает файл и возвращает артикулы из первой колонки.
//
// Файл читается потоком из временного хранилища, без временных файлов на диске:
// дополнительные отчеты исполняются в безопасном режиме, где доступ к файловой
// системе закрыт.
//
// Параметры:
// АдресФайла - Строка - адрес двоичных данных файла во временном хранилище.
// ИмяФайла - Строка - имя файла с расширением, по нему выбирается способ чтения.
//
// Возвращаемое значение:
// Массив из Строка - непустые значения первой колонки, по одному на строку файла.
//
&НаСервереБезКонтекста
Функция АртикулыИзФайла(АдресФайла, ИмяФайла)
Артикулы = Новый Массив;
Точка = СтрНайти(ИмяФайла, ".", НаправлениеПоиска.СКонца);
Расширение = ?(Точка = 0, "", НРег(Сред(ИмяФайла, Точка + 1)));
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресФайла);
Если Расширение = "txt" Тогда
Чтение = Новый ЧтениеТекста(ДвоичныеДанные.ОткрытьПотокДляЧтения(), КодировкаТекста.UTF8);
СтрокаФайла = Чтение.ПрочитатьСтроку();
Пока СтрокаФайла <> Неопределено Цикл
ДобавитьАртикул(Артикулы, СтрокаФайла);
СтрокаФайла = Чтение.ПрочитатьСтроку();
КонецЦикла;
Чтение.Закрыть();
Иначе
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.Прочитать(ДвоичныеДанные.ОткрытьПотокДляЧтения(),
СпособЧтенияЗначенийТабличногоДокумента.Значение);
Для НомерСтроки = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл
ДобавитьАртикул(Артикулы, ТабличныйДокумент.Область(НомерСтроки, 1, НомерСтроки, 1).Текст);
КонецЦикла;
КонецЕсли;
Возврат Артикулы;
КонецФункции
// Добавляет в массив очищенное значение артикула, если оно непустое.
//
// Параметры:
// Артикулы - Массив из Строка - приемник.
// Значение - Произвольный - исходное значение ячейки или строки файла.
//
&НаСервереБезКонтекста
Процедура ДобавитьАртикул(Артикулы, Значение)
Артикул = СокрЛП(Строка(Значение));
Если Не ПустаяСтрока(Артикул) Тогда
Артикулы.Добавить(Артикул);
КонецЕсли;
КонецПроцедуры
#КонецОбласти