Куда ни глянь, в интернете чаще всего предлагается обработка и чтение большого файла csv в 1С при помощи загрузки в «текстовыйДокумент». Примерно так:
ТекстДок = Новый ТекстовыйДокумент; ТекстДок.Прочитать(ИмяВременногоФайлаХар); Для Индекс = 2 По ТекстДок.КоличествоСтрок() Цикл СтрокаФайла = ТекстДок.ПолучитьСтроку(Индекс); конеццикла;
Что в корне не верно, при обработке большого csv файла, так как в этом случае весь файл вычитывается предварительно в память. А она не безразмерная в большинстве случаев. Правильный же способ обработки — построчное чтение файла. Примерно так:
Текст = Новый ЧтениеТекста(ИмяВременногоФайлаХар, КодировкаТекста.ANSI);
Стр = Текст.ПрочитатьСтроку();
Пока Стр <> Неопределено Цикл
Сообщить(Стр);
Стр = Текст.ПрочитатьСтроку();
МассивПодстрок = СтрРазделить(Стр, ";");
инф=Новый Структура("то,лс,ипу,окпу,нс,улица,дом,квартира");
инф.то =СокрЛП(МассивПодстрок[2]);
инф.лс =СокрЛП(СтрЗаменить(МассивПодстрок[3],"-",""));
инф.ипу =СокрЛП(МассивПодстрок[31]);
инф.окпу =СокрЛП(МассивПодстрок[92]);
инф.нс =СокрЛП(МассивПодстрок[8]);
инф.улица =СокрЛП(МассивПодстрок[9]);
инф.дом =СокрЛП(МассивПодстрок[10]);
инф.квартира=СокрЛП(МассивПодстрок[11]);
ИсходныеДанные.субабоненты.Добавить(инф);
КонецЦикла;
До недавнего времени (еще несколько лет назад) для хранения данных учётных записей в 1С единственной защитой было — показывать поле с паролем со «звездочками». Сам же пароль хранился в практически открытом виде в реквизитах формы. Ну.. возможно это и не безопасно.. Новая методика хранения чувствительных данных в 1С призвана эту безопасность увеличить. Работа с безопасным хранилищем в 1с, Поэтому в БСП были внедрены функции общего назначения «ПрочитатьДанныеИзБезопасногоХранилища» и «ЗаписатьДанныеВБезопасноеХранилище».
В чём разница между хранением в реквизитах и новой методикой:
Имея доступ к объекту метаданных, пользователь может прочитать содержимое реквизита с паролем, что невозможно при использовании безопасного хранилища. Для исключения случаев несанкционированного доступа к безопасному хранилищу получение и запись данных (паролей) возможна только в привилегированном режиме.
Данные в безопасном хранилище хранятся в закрытом виде и тем самым исключаются случаи непредумышленной «засветки» паролей.
Безопасное хранилище исключено из планов обмена, что предотвращает утечку паролей из информационной базы при обмене данными.
Задача: выгрузить табличную часть формы в файл формата XLSX. К сожалению на прямую это не сделать, но зато мы можем воспользоваться функционалом компонента ПостроительОтчета, который в свою очередь понимает на входе таблицу значений. В итоге нам остаётся лишь выгрузить табличную часть в таблицу значений, которую в свою оочередь скормить построителю отчетов. На выходе будет ТабличныйДокумент, который уже штатно может сохраняться в т.ч. и в формат xlsx. Код получается примерно такой::
&НаСервере
Функция ЭкспортВExcelНаСервере()
ТабДок = Новый ТабличныйДокумент;
Тз = Новый ТаблицаЗначений;
тз.Колонки.Добавить("Отделение");
тз.Колонки.Добавить("Подразделение");
тз.Колонки.Добавить("ЛС");
тз.Колонки.Добавить("КодСопоставления");
тз.Колонки.Добавить("ДатаРождения");
тз.Колонки.Добавить("МестоРождения");
тз.Колонки.Добавить("СерияПаспорта");
тз.Колонки.Добавить("НомерПаспорта");
тз.Колонки.Добавить("СерияНомерПаспорта");
тз.Колонки.Добавить("РезультатПроверки");
для каждого стр из объект.РезультатСопоставления цикл
нс=тз.Добавить();
нс.Отделение=стр.Отделение;
нс.Подразделение=стр.Подразделение;
нс.ЛС=стр.ЛС;
нс.КодСопоставления=стр.КодСопоставления;
нс.ДатаРождения=стр.ДатаРождения;
нс.МестоРождения=стр.МестоРождения;
нс.СерияПаспорта=стр.СерияПаспортаС;
нс.НомерПаспорта=стр.НомерПаспортаС;
нс.СерияНомерПаспорта=стр.СерияНомерПаспорта;
нс.РезультатПроверки=стр.РезультатПроверки;
конеццикла;
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(Тз);
Построитель.Выполнить();
Построитель.Вывести(ТабДок);
ИмяВременногоФайлаХар = ПолучитьИмяВременногоФайла(".xlsx");
ТабДок.Записать(ИмяВременногоФайлаХар,ТипФайлаТабличногоДокумента.XLSX);
сообщить(ИмяВременногоФайлаХар);
Двоичное=Новый ДвоичныеДанные(ИмяВременногоФайлаХар);
Адрес=ПоместитьВоВременноеХранилище(Двоичное,ЭтаФорма.УникальныйИдентификатор);
Возврат Адрес;
КонецФункции
&НаКлиенте
Процедура ЭкспортВExcel(Команда)
Адрес=ЭкспортВExcelНаСервере();
Описание=Новый ОписаниеПередаваемогоФайла(ПолучитьИмяВременногоФайла(".xlsx"),Адрес);
МассивОписаний=Новый Массив;
МассивОписаний.Добавить(Описание);
ПолучитьФайлы(МассивОписаний,,,Ложь);
Для Каждого фф Из МассивОписаний Цикл
ЗапуститьПриложение(фф.Имя);
КонецЦикла;
КонецПроцедуры
Пользователь нажимает кнопку «Экспорт в эксель», на сервере формируется файл и передаётся на клиент. На клиенте он открывается приложением по умолчанию для данного формата файла. Код получился кросс платформенный, что в наше время очень актуально.
Прилетела задача прочитать сообщение из почтового ящика по протоколу IMAP. Последнее из пришедших. В принципе в 1С есть штатный функционал для чтения почты, поэтому пример всё сам расскажет за себя:
Процедура ЧитнутьНаСервереImap()
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АутентификацияPOP3 = Ложь;
Профиль.АутентификацияSMTP = Ложь;
// IMAP
Профиль.ИспользоватьSSLIMAP = Истина;
Профиль.АдресСервераIMAP = "цукацу-укацука.уцкацук.ru";
Профиль.ПортIMAP = "993";
Профиль.ПользовательIMAP = "укацу@укацукау.ru";
Профиль.ПарольIMAP = "цукацукацук";
Профиль.ТолькоЗащищеннаяАутентификацияIMAP=Ложь;
Почта = Новый ИнтернетПочта;
Сообщ = Новый СообщениеПользователю();
Почта.Подключиться(Профиль, ПротоколИнтернетПочты.IMAP); //ПротоколИнтернетПочты.POP3
заголовки=Почта.ПолучитьЗаголовки();
если заголовки.Количество()>0 тогда
ПоследнийЗаголовок=Новый Массив();
ПоследнийЗаголовок.Добавить(заголовки[заголовки.Количество()-1]);
МассивСообщений = Новый Массив;
МассивСообщений = Почта.Выбрать(Ложь,ПоследнийЗаголовок);
ТекстСообщения=МассивСообщений[0].тексты[0].Текст;
сообщить(ТекстСообщения);
конецесли;
Почта.Отключиться();
КонецПроцедуры
Из особенностей логики — сначала вычитываю заголовки, т.к. если почты много, то чтение писем будет ОЧЕНЬ долгим. Далее получаю последний по счету заголовок, и вычитываю текст конкретно уже этого письма.
Задача добавление рабочих дней к дате (добавить рабочие дни к дате) встречается довольно часто. И штатно должна решаться с помощью стандартного функционала БСП — «Производственный календарь». Например так:
Функция ДобавитьКДатеРабочиеДни(ДатаНач,ЧислоРабочихДней) экспорт
Запрос=Новый Запрос;
Запрос.Текст="ВЫБРАТЬ
| ВЫБОР
| КОГДА РегламентированныйПроизводственныйКалендарь.ВидДня = &РабочийДень
| ИЛИ РегламентированныйПроизводственныйКалендарь.ВидДня = &ПредпраздничныйДень
| ТОГДА 1
| ИНАЧЕ 0
| КОНЕЦ КАК ЧислоРабочихДней,
| РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК ДатаКалендаря
|ПОМЕСТИТЬ ТЗ
|ИЗ
| РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
|ГДЕ
| РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &ДатаНач И &ДатаКон
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТЗ.ДатаКалендаря,
| СУММА(ТЗ1.ЧислоРабочихДней) КАК ЧислоРабочихДней
|ПОМЕСТИТЬ ТЗНакопл
|ИЗ
| ТЗ КАК ТЗ
| ЛЕВОЕ СОЕДИНЕНИЕ ТЗ КАК ТЗ1
| ПО (ТЗ1.ДатаКалендаря <= ТЗ.ДатаКалендаря)
|
|СГРУППИРОВАТЬ ПО
| ТЗ.ДатаКалендаря
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| МАКСИМУМ(ТЗ.ДатаКалендаря) КАК ДатаКалендаря
|ИЗ
| ТЗНакопл КАК ТЗ
|ГДЕ
| ТЗ.ЧислоРабочихДней = &ЧислоРабочихДней";
Запрос.УстановитьПараметр("ДатаНач", ДатаНач);
ЧислоНедель = Цел(ЧислоРабочихДней/5+0.5);
ЧислоВыходныхДней = ЧислоНедель*2;
МаксимальноеКоличествоПраздничныхДнейПодряд = 8; //РождественскиеКаникулы
ДатаКон = ДатаНач+(ЧислоВыходныхДней+ЧислоРабочихДней+МаксимальноеКоличествоПраздничныхДнейПодряд)*24*60*60;
Запрос.УстановитьПараметр("ДатаКон",ДатаКон);
Запрос.УстановитьПараметр("ЧислоРабочихДней",ЧислоРабочихДней);
Запрос.УстановитьПараметр("РабочийДень", Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий);
Запрос.УстановитьПараметр("ПредпраздничныйДень", Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный);
Выборка = Запрос.Выполнить().Выбрать();
Результат = 0;
Если Выборка.Следующий() Тогда
Результат = КонецДня(Выборка.ДатаКалендаря)+1;
Конецесли;
Возврат Результат;
КонецФункции
Однако не всё же не все конфигурации содержат производственный календарь. Например почему-то обделено Делопроизводство 2.0. Что-бы не городить огород,, решил задачу «в лоб», без учёта праздничных дней — просто проверяю выпадение даты на субботу-воскресенье. В моём случае этого хватило.
Функция ДобавитьКДатеРабочиеДни(ДатаПроверки,дней)
добавлено=0;
пока добавлено<>дней цикл
ДатаПроверки=ДатаПроверки+86400;
Если ДеньНедели(ДатаПроверки) <> 6 ИЛИ ДеньНедели(ДатаПроверки) <> 7 Тогда
добавлено=добавлено+1;
конецесли;
конеццикла;
Возврат ДатаПроверки;
КонецФункции