Tuesday, July 29, 2014

Генератор паролей в 1С с проверкой сложности

Задали мне задачку импортировать пользователей в Битрикс с требование генерации сложных паролей с 1С. Импорт с Битрикс отдельная тема, а вот сложные пароли и их валидность опишу тут.
Фактически требование сводилось к мин количеству символов = 8, должны быть буквы нижнего и верхнего регистра, цифры и спец. символы.
Вот что из этого получилось:

Функция СгенерироватьПароль(МинДлинаПароля=8, СложныйПароль=Истина)
 ПарольВалиден = Ложь;
 
 Пока НЕ ПарольВалиден Цикл
  ГСЧ = Новый ГенераторСлучайныхЧисел(Секунда(ТекущаяДата()));
  ТПароль = СтрЗаменить(Строка(Новый УникальныйИдентификатор()),"-","");
  
  Если не СложныйПароль тогда
   Возврат Лев(ТПароль,МинДлинаПароля);
  Иначе
   НобходимыеСимволяДляСложности = ".,<>/?;:'[]{}\`~!@#$%^&*()-_+=";
   МаксСимволов  =  МинДлинаПароля+ГСЧ.СлучайноеЧисло(0,4);
   ТПароль = Лев(ТПароль,МаксСимволов);
   Для Сим=1 по МаксСимволов Цикл
    Если Сим>1 И Булево(ГСЧ.СлучайноеЧисло(0,1)) И Найти(НобходимыеСимволяДляСложности,Сред(ТПароль,Сим-1,1))=0 тогда
     ТПароль = Лев(ТПароль,Сим)+Сред(НобходимыеСимволяДляСложности,ГСЧ.СлучайноеЧисло(0,30),1)+Сред(ТПароль,Сим+1);
     Сим = Сим+1;
     ТПароль = Сред(ТПароль,1,МаксСимволов);
    КонецЕсли;
    Если Булево(ГСЧ.СлучайноеЧисло(0,1)) тогда
     ТПароль = Лев(ТПароль,Сим-1)+ВРег(Сред(ТПароль,Сим,1))+Сред(ТПароль,Сим+1);
    КонецЕсли;
   КонецЦикла;
  КонецЕсли;
  
  //Проверка валидности пароля
  //((?=.*[a-z])(?=.*\d)(?=.*[\.,<>/\?;:'\[\]\{\}\\`~!@#$%^&*()-_+=])(?=.*[A-Z]).{6,})
  
  RegExp = Новый COMОбъект("VBScript.RegExp");
  //СтруктураФайлов = Новый СписокЗначений;
  RegExp.MultiLine = Истина; // истина — текст многострочный, ложь — одна строка 
  RegExp.Global = Истина; // истина — поиск по всей строке, ложь — до первого совпадения 
  RegExp.IgnoreCase = Ложь; // истина — игнорировать регистр строки при поиске 
  RegExp.Pattern = "^((?=.*[a-z])(?=.*\d)(?=.*[\.,<>/\?;:'\[\]\{\}\\`~!@#$%^&\*()-_+=])(?=.*[A-Z]).{8,})$";
  ПарольВалиден = RegExp.Test(ТПароль);
 КонецЦикла;
 Возврат ТПароль;
КонецФункции

Monday, July 21, 2014

Формирование отчета СКД с картинками в управляемых формах 1С УТ11

Поставили мне задачу сформировать отчет с картинками. Очень давно пользуюсь СКД, но как то нормально у системы с картинками не сложилось. поэтому пришлось гуглить.
Как итог вид отчета

Натолкнулся на проблему, в нете все решения сделаны базово. Мне необходимо было сделать так что бы была возможность выводить несколько изображений и они не были привязаны к определенным колонкам.
Фактически необходимо показать изображение которое стоит основным в справочнике номенклатуры, а также все изображения из справочника "ПрисоединенныеФайлы". В этой обработке возможно будет ошибка, так как я не проверяю, это картинка или нет, необходимо доделывать проверку.

В итоге запрос из схемы компоновки данных:

ВЫБРАТЬ
НоменклатураПрисоединенныеФайлы.Ссылка КАК Файл,
НоменклатураПрисоединенныеФайлы.ВидФайла,
НоменклатураПрисоединенныеФайлы.ФайлХранилище,
НоменклатураПрисоединенныеФайлы.ВладелецФайла,
ПрисоединенныеФайлы.ХранимыйФайл КАК Картинка,
СпрНоменклатура.Ссылка КАК Номенклатура,
ПрисоединенныеФайлы.ХранимыйФайл КАК КоличествоФайлов,
СпрНоменклатура.Ссылка КАК КоличествоНоменклатуры,
НоменклатураПрисоединенныеФайлы.ВладелецФайла КАК КоличествоНоменклатурыСФайлами,
СпрНоменклатура.ФайлКартинки
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.НоменклатураПрисоединенныеФайлы КАК НоменклатураПрисоединенныеФайлы
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПрисоединенныеФайлы КАК ПрисоединенныеФайлы
ПО НоменклатураПрисоединенныеФайлы.Ссылка = ПрисоединенныеФайлы.ПрисоединенныйФайл
ПО СпрНоменклатура.Ссылка = НоменклатураПрисоединенныеФайлы.ВладелецФайла
Плюсом к моей задаче необходимо было оценить сколько файлов прикреплено.
Добавляем параметр ширину колонки, для красоты вывода
И оформляем настройки


Выводим только заполненные дополнительные строки


И код модуля




Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
 СтандартнаяОбработка = Ложь;
 ДокументРезультат.Очистить();
 НастройкиОтчета = КомпоновщикНастроек.ПолучитьНастройки();
 КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
 Макет = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиОтчета, ДанныеРасшифровки);
 ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
 ПроцессорКомпоновки.Инициализировать(Макет, , ДанныеРасшифровки);
 ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
 ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
 
 ИмяКолонкиИзображения = "Файл";
 ШиринаКолонкиИзображения = ВернутьЗначениеПараметраНастройкиСКД(КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы, "ШиринаКолонкиИзображения", 20); 
 
 ПроцессорВывода.НачатьВывод();
 Пока Истина Цикл
  
  ЭлементРезультата = ПроцессорКомпоновки.Следующий();
  
  Если ЭлементРезультата = Неопределено Тогда
   Прервать;
  КонецЕсли; 
  
  ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
  Если ЭлементРезультата.ЗначенияПараметров.Количество() = 0 Тогда
   Продолжить;
  КонецЕсли;
  
  
  Для Каждого ЭлементПараметра Из ЭлементРезультата.ЗначенияПараметров Цикл
   Если ТипЗнч(ЭлементПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
    Поля = ДанныеРасшифровки.Элементы[ЭлементПараметра.Значение].ПолучитьПоля();
    Для Каждого Поле Из Поля Цикл
     Если ТипЗнч(Поле.Значение) = Тип("СправочникСсылка.НоменклатураПрисоединенныеФайлы") Тогда
      Если Поле.Значение.Пустая() Тогда Продолжить; КонецЕсли;
      //Поиск номера колонки, с нужным именем ИмяКолонкиИзображения, для таки вывода изображения
      Для НомерКолонки = 1 По ДокументРезультат.ШиринаТаблицы Цикл
       Расшифровка = ДокументРезультат.Область(ДокументРезультат.ВысотаТаблицы, НомерКолонки, ДокументРезультат.ВысотаТаблицы, НомерКолонки).Расшифровка;
       Если Расшифровка = Неопределено Тогда Продолжить; КонецЕсли;
       Поля = ДанныеРасшифровки.Элементы.Получить(Расшифровка).ПолучитьПоля();
       Для Каждого знчПоле Из Поля Цикл
        Если знчПоле.Значение  = Поле.Значение тогда
         ОбластьИзображения = ДокументРезультат.Область(ДокументРезультат.ВысотаТаблицы, НомерКолонки);
         ВывестиИзображениеЭлементаНоменклатуры(ДокументРезультат, Поле.Значение, ОбластьИзображения, ШиринаКолонкиИзображения);   
        КонецЕсли;
       КонецЦикла;
      КонецЦикла;
     КонецЕсли;
    КонецЦикла;
   КонецЕсли;
  КонецЦикла;  
 КонецЦикла;
 ПроцессорВывода.ЗакончитьВывод();
КонецПроцедуры

Процедура ВывестиИзображениеЭлементаНоменклатуры(ТД, ЭлементСправочника, Область, ШиринаКолонкиИзображения)
 Если ЭлементСправочника.ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе Тогда
  СтуктураРег = РегистрыСведений.ПрисоединенныеФайлы.Получить(Новый Структура("ПрисоединенныйФайл,ВидФайла", ЭлементСправочника,ЭлементСправочника.ВидФайла));
  ДанныеКартинки = СтуктураРег.ХранимыйФайл.Получить();
 Иначе
  ДанныеКартинки = ?(ЗначениеЗаполнено(ЭлементСправочника.Том.ПолныйПутьWindows), ЭлементСправочника.Том.ПолныйПутьWindows, ЭлементСправочника.Том.ПолныйПутьLinux)
  + ЭлементСправочника.ПутьКФайлу;
 КонецЕсли;
 Рисунок = ВывестиИзображениеВОбластиТД(ДанныеКартинки, ТД, Область);
 Область.АвтоВысотаСтроки = Ложь;
 Область.ВысотаСтроки = ШиринаКолонкиИзображения * 1.31 / 0.3759;// Среднее значение пункта 1 пункт = 0.3759 мм (по Wiki)
 Область.Расшифровка = ЭлементСправочника;
 Рисунок.ЦветЛинии = Область.ЦветРамки;
КонецПроцедуры 


Функция ВывестиИзображениеВОбластиТД(ДанныеКартинки, ТД, Область)
 Изображение = ТД.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
 Изображение.РазмерКартинки = РазмерКартинки.АвтоРазмер;
 Индекс = ТД.Рисунки.Индекс(Изображение);
 ТД.Рисунки[Индекс].Картинка = Новый Картинка(ДанныеКартинки, Истина);
 ТД.Рисунки[Индекс].Расположить(Область);
 Возврат ТД.Рисунки[Индекс]; 
КонецФункции


Функция ВернутьЗначениеПараметраНастройкиСКД(КоллекцияЭлементовНастройки, ИмяНастройки, ЗначениеПоУмолчанию = Неопределено)
 
 Настройка = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти(ИмяНастройки);
 Если Настройка = Неопределено Тогда Возврат ЗначениеПоУмолчанию; КонецЕсли;
 НастрокаПоИД = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(Настройка.ИдентификаторПользовательскойНастройки);
 Если Не ЗначениеЗаполнено(НастрокаПоИД.Значение) Тогда 
  Если Не ЗначениеПоУмолчанию = Неопределено Тогда
   НастрокаПоИД.Значение = ЗначениеПоУмолчанию;
  КонецЕсли;
 КонецЕсли;
 Возврат ?(НастрокаПоИД.Использование, НастрокаПоИД.Значение, ЗначениеПоУмолчанию); 
КонецФункции