Библиотека универсальных функций и процедур (v 1.3)

Привожу тексты различных универсальных функций и процедур, которыми постоянно пользуюсь.
Некоторые функции достаточно специфичны, но многими пользуюсь практически каждый день.

Все функции писал сам (может быть, пару функций где-то позаимствовал, но сейчас уже не вспомню, где и когда). Не буду претендовать на оригинальность, возможно, ряду функций существует достаточно аналогов, в т.ч. на данном сайте.

Надеюсь, кому-нибудь они будут полезны.

#Область РаботаСПримитивнымиТипами

#Область РаботаСоСтроками

Функция ЦифровыеСимволы() Экспорт
Возврат "0123456789";
КонецФункции // ()

Функция ПустойУИД() Экспорт

Возврат "00000000-0000-0000-0000-000000000000";

КонецФункции // ()

Функция ИнвертироватьСтроку(Знач Строка) Экспорт

НоваяСтрока = "";

Если Строка <> "" Тогда
ДлинаСтроки = СтрДлина(Строка);

Для Индекс = 0 По ДлинаСтроки-1 Цикл

НоваяСтрока = НоваяСтрока+Сред(Строка,ДлинаСтроки-Индекс,1)

КонецЦикла;

КонецЕсли;

Возврат НоваяСтрока;

КонецФункции // ()

Функция СтрОбрезатьСправа(Знач Строка,ЧислоСимволов) Экспорт

Возврат Лев(Строка,СтрДлина(Строка)-ЧислоСимволов);

КонецФункции

Функция СтрОбрезатьСлева(Знач Строка,ЧислоСимволов) Экспорт

Возврат Прав(Строка,СтрДлина(Строка)-ЧислоСимволов);

КонецФункции

Функция СтрЗаменитьСправа(Знач Строка,ЧислоСимволов,СтрокаЗамены) Экспорт

Возврат СтрОбрезатьСправа(Строка,ЧислоСимволов)+СтрокаЗамены;

КонецФункции

Функция СтрЗаменитьСлева(Знач Строка,ЧислоСимволов,СтрокаЗамены) Экспорт

Возврат СтрокаЗамены+СтрОбрезатьСлева(Строка,ЧислоСимволов);

КонецФункции

Функция СобратьПредставлениеЗначений(МассивЗначений,Разделитель = " ",ФорматнаяСтрока = "") Экспорт

МассивСоединения = Новый Массив;
Форматировать = не ПустаяСтрока(ФорматнаяСтрока);

Если Форматировать Тогда
ФорматныйТип = Новый ОписаниеТипов("Число,Дата,Булево");
Иначе
ФорматныйТип = Неопределено;
КонецЕсли;

Для каждого ЭлементМассива Из МассивЗначений Цикл

Если Форматировать и ФорматныйТип.СодержитТип(ТипЗнч(ЭлементМассива)) Тогда
МассивСоединения.Добавить(Формат(ЭлементМассива,ФорматнаяСтрока));
Иначе
МассивСоединения.Добавить(Строка(ЭлементМассива));
КонецЕсли;

КонецЦикла;

Возврат СтрСоединить(МассивСоединения,Разделитель);

КонецФункции // ()

Процедура ДобавитьСтрокуТекста(Текст,Строка) Экспорт

Если не ПустаяСтрока(Строка) Тогда
Текст = Текст+?(ПустаяСтрока(Текст),"","
|")+Строка;
КонецЕсли;

КонецПроцедуры

Функция СтрУбратьНедопустимыеСимволы(Знач Строка,ДопустимыеСимволы) Экспорт
НоваяСтрока = "";
ЧислоСимволов = СтрДлина(Строка);

Для Индекс = 1 По ЧислоСимволов Цикл
Символ = Сред(Строка,Индекс,1);
Если Найти(ДопустимыеСимволы,Символ) > 0 Тогда
НоваяСтрока = НоваяСтрока+Символ;
КонецЕсли;
КонецЦикла;

Возврат НоваяСтрока;
КонецФункции // ()

Функция ПолучитьВхожденияПодстроки(Знач Строка,ПодстрокаПоиска) Экспорт
СтрокаВхождений = Строка;
МассивВхождений = Новый Массив;
ДлинаПодстроки = СтрДлина(ПодстрокаПоиска);
Обрезано = 0;

Пока Истина Цикл
Поиск = Найти(СтрокаВхождений,ПодстрокаПоиска);

Если Поиск > 0 Тогда
МассивВхождений.Добавить(Обрезано+Поиск);
СтрокаВхождений = СтрОбрезатьСлева(СтрокаВхождений,Поиск+ДлинаПодстроки-1);
Обрезано = Обрезано+Поиск+ДлинаПодстроки-1;
Иначе
Прервать;
КонецЕсли;

Если СтрДлина(СтрокаВхождений) < ДлинаПодстроки Тогда
Прервать;
КонецЕсли;

КонецЦикла;

Возврат МассивВхождений;
КонецФункции

Процедура СтрГрупповаяЗамена(Строка,СоответствиеЗамен) Экспорт
Для каждого ЭлементСоответствия Из СоответствиеЗамен Цикл
Строка = СтрЗаменить(Строка,ЭлементСоответствия.Ключ,ЭлементСоответствия.Значение);
КонецЦикла;
КонецПроцедуры

Процедура СтрУбратьПодрядидущиеСимволы(Строка,СтрокаЗамены) Экспорт

Для Индекс = 1 По СтрДлина(СтрокаЗамены) Цикл
СимволЗамены = Сред(СтрокаЗамены,Индекс,1);

Пока Истина Цикл
ПодстрокаЗамены = СимволЗамены+СимволЗамены;

Если Найти(Строка,ПодстрокаЗамены) > 0 Тогда
Строка = СтрЗаменить(Строка,ПодстрокаЗамены,СимволЗамены);
Иначе
Прервать;
КонецЕсли;

КонецЦикла;

КонецЦикла;

КонецПроцедуры

Функция ПолучитьЧислоИзСтроки(Знач Строка,ВернутьЧисло = Ложь) Экспорт

Ошибка = ПустаяСтрока(Строка);

Если Ошибка Тогда
Возврат ?(ВернутьЧисло,0,Неопределено);
КонецЕсли;

ЕстьРазделитель = Ложь;
Строка = СтрЗаменить(СокрЛП(Строка)," ","");
Отрицательное = Лев(Строка,1) = "-";
ЦифровойРяд = ЦифровыеСимволы();

Если Отрицательное Тогда
Строка = СтрОбрезатьСлева(Строка,1);
КонецЕсли;

Для Индекс = 1 По СтрДлина(Строка) Цикл
Знак = Сред(Строка,Индекс,1);

Если Знак = "," или Знак = "." Тогда

Если ЕстьРазделитель Тогда
Ошибка = Истина;
Прервать;
Иначе
ЕстьРазделитель = Истина;
КонецЕсли;

ИначеЕсли Найти(ЦифровойРяд,Знак) = 0 Тогда
Ошибка = Истина;
Прервать;
КонецЕсли;

КонецЦикла;

Если Отрицательное Тогда
Строка = "-"+Строка;
КонецЕсли;

Возврат ?(Ошибка,?(ВернутьЧисло,0,Неопределено),Число(Строка));

КонецФункции

#КонецОбласти

Функция _Число(Значение) Экспорт
Если Значение = Неопределено Тогда
Возврат 0;
Иначе
Возврат Значение;
КонецЕсли;
КонецФункции

Функция ПроверкаДеления(Делимое,Делитель) Экспорт
Возврат ?(Делитель = 0,0,Делимое/Делитель);
КонецФункции

Функция ЗначенияЗаполнены(МассивЗначений) Экспорт

Результат = Истина;

Для каждого ЭлементМассива Из МассивЗначений Цикл
Результат = Мин(Результат,ЗначениеЗаполнено(ЭлементМассива));
КонецЦикла;

Возврат Результат;

КонецФункции

Функция ДатыРавны(Дата1,Дата2) Экспорт
Возврат НачалоДня(Дата1) = НачалоДня(Дата2);
КонецФункции // ()

#КонецОбласти

#Область РаботаСМассивом

Функция СоздатьМассив(Элемент1 = Неопределено,
Элемент2 = Неопределено,
Элемент3 = Неопределено,
Элемент4 = Неопределено,
Элемент5 = Неопределено,
Элемент6 = Неопределено,
Элемент7 = Неопределено,
Элемент8 = Неопределено) Экспорт

МассивЭлементов = Новый Массив;
ДобавитьЭлементВМассив(МассивЭлементов,Элемент1);
ДобавитьЭлементВМассив(МассивЭлементов,Элемент2);
ДобавитьЭлементВМассив(МассивЭлементов,Элемент3);
ДобавитьЭлементВМассив(МассивЭлементов,Элемент4);
ДобавитьЭлементВМассив(МассивЭлементов,Элемент5);
ДобавитьЭлементВМассив(МассивЭлементов,Элемент6);
ДобавитьЭлементВМассив(МассивЭлементов,Элемент7);
ДобавитьЭлементВМассив(МассивЭлементов,Элемент8);
Возврат МассивЭлементов;

КонецФункции

Процедура ДобавитьЭлементВМассив(Массив,Элемент) Экспорт

Если Элемент <> Неопределено Тогда
Массив.Добавить(Элемент);
КонецЕсли;

КонецПроцедуры

Функция ПолучитьМассивЗначенийКлючей(Знач Источник,Знач СтрокаКлючей,Разделитель = ",") Экспорт

МассивКлючей = СтрРазделить(СтрокаКлючей,Разделитель);
МассивЗначений = Новый Массив;

Для каждого ЭлементМассива Из МассивКлючей Цикл
МассивЗначений.Добавить(Источник[ЭлементМассива]);
КонецЦикла;

Возврат МассивЗначений;

КонецФункции // ()

#КонецОбласти

#Область РаботаССоответствием

Процедура ВставитьЗначениеВложенногоСоответствия(Соответствие,МассивКлючей,Значение) Экспорт

ТекущееСоответствие = Соответствие;
ЧислоКлючей = МассивКлючей.Количество();

Если ЧислоКлючей > 1 Тогда

Для Индекс = 0 По ЧислоКлючей-2 Цикл
Элемент = МассивКлючей[Индекс];
ДанныеСоответствия = ТекущееСоответствие[Элемент];

Если ДанныеСоответствия = Неопределено Тогда
ТекущееСоответствие.Вставить(Элемент,Новый Соответствие);
КонецЕсли;

ТекущееСоответствие = ТекущееСоответствие[Элемент];
КонецЦикла;

КонецЕсли;

ТекущееСоответствие.Вставить(МассивКлючей[ЧислоКлючей-1],Значение);

КонецПроцедуры

Функция ПолучитьЗначениеВложенногоСоответствия(Соответствие,МассивКлючей) Экспорт

ТекущееСоответствие = Соответствие;

Для каждого Элемент Из МассивКлючей Цикл

ДанныеСоответствия = ТекущееСоответствие[Элемент];

Если ДанныеСоответствия = Неопределено Тогда
Возврат Неопределено;
Прервать;
КонецЕсли;

ТекущееСоответствие = ДанныеСоответствия;

КонецЦикла;

Возврат ДанныеСоответствия;

КонецФункции

Процедура АгрегироватьЗначениеВложенногоСоответствия(Соответствие,МассивКлючей,Значение) Экспорт

ТекущееЗначение = ПолучитьЗначениеВложенногоСоответствия(Соответствие,МассивКлючей);

Если ТипЗнч(ТекущееЗначение) = Тип("Число") Тогда
ВставитьЗначениеВложенногоСоответствия(Соответствие,МассивКлючей,ТекущееЗначение+Значение);
Иначе
ВставитьЗначениеВложенногоСоответствия(Соответствие,МассивКлючей,Значение);
КонецЕсли;

КонецПроцедуры

Функция СоздатьСоответствиеТаблицы(МенеджерТаблицы,ИмяРеквизита) Экспорт

СоответствиеТаблицы = Новый Соответствие;
Выборка = МенеджерТаблицы.Выбрать();

Пока Выборка.Следующий() Цикл
СоответствиеТаблицы.Вставить(Выборка.Ссылка,Выборка[ИмяРеквизита]);
КонецЦикла;

Возврат СоответствиеТаблицы;

КонецФункции

#КонецОбласти

#Область РаботаСоСтруктурой

Функция ПолучитьСтруктуруПоКлючам(СтрокаКлючей,ДанныеЗаполнения = Неопределено,МассивЗначений = Неопределено,БазоваяСтруктура = Неопределено) Экспорт

СтруктураПараметров = Новый Структура(СтрокаКлючей);

Если ДанныеЗаполнения <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтруктураПараметров,ДанныеЗаполнения);
КонецЕсли;

Если МассивЗначений <> Неопределено Тогда
Индекс = 0;
Количество = МассивЗначений.Количество();

Для каждого ЭлементСтруктуры Из СтруктураПараметров Цикл

Если Индекс >= Количество Тогда
Прервать;
КонецЕсли;

СтруктураПараметров[ЭлементСтруктуры.Ключ] = МассивЗначений[Индекс];
Индекс = Индекс+1;
КонецЦикла;

КонецЕсли;

Если БазоваяСтруктура <> Неопределено Тогда
Для каждого ЭлементСтруктуры Из СтруктураПараметров Цикл
БазоваяСтруктура.Вставить(ЭлементСтруктуры.Ключ,ЭлементСтруктуры.Значение);
КонецЦикла;
КонецЕсли;

Возврат СтруктураПараметров;

КонецФункции // ()

Функция СравнитьЗначенияКлючей(СтрокаКлючей,Источник1,Источник2) Экспорт

МассивКлючей = СтрРазделить(СтрокаКлючей,",");
Равны = Истина;

Для каждого ЭлементМассива Из МассивКлючей Цикл
Если Источник1[ЭлементМассива] <> Источник2[ЭлементМассива] Тогда
Равны = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;

Возврат Равны;

КонецФункции // ()

#КонецОбласти

#Если не (ТонкийКлиент или ВебКлиент) Тогда

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Работа со списком значений
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Функция ВыгрузитьСписокЗначенийВТаблицуЗначений(Знач Источник,ОписаниеТиповЗначения) Экспорт

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Значение",ОписаниеТиповЗначения);
ТЗ.Колонки.Добавить("Пометка",Новый ОписаниеТипов("Булево"));
ТЗ.Колонки.Добавить("Представление",Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(256)));

Для каждого ЭлементСписка Из Источник Цикл
Строка = ТЗ.Добавить();
ЗаполнитьЗначенияСвойств(Строка,ЭлементСписка);
КонецЦикла;

Возврат ТЗ;

КонецФункции // ()

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Работа с таблицей значений
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Процедура ДобавитьСтрокиТаблицыЗначений(ТаблицаПриемник,Знач Источник) Экспорт

Для каждого Строка Из Источник Цикл
НоваяСтрока = ТаблицаПриемник.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока,Строка);
КонецЦикла;

КонецПроцедуры

Процедура УдалитьСтрокиТаблицыЗначений(Таблица,СтруктураПоиска = Неопределено,МассивЭлементов = Неопределено) Экспорт

Если СтруктураПоиска <> Неопределено Тогда
МассивЭлементов = Таблица.НайтиСтроки(СтруктураПоиска);
ИначеЕсли МассивЭлементов = Неопределено Тогда
МассивЭлементов = Новый Массив;
КонецЕсли;

Для каждого ЭлементМассива Из МассивЭлементов Цикл
Таблица.Удалить(ЭлементМассива);
КонецЦикла;

КонецПроцедуры

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Работа с деревом значений
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Функция ВыгрузитьДеревоЗначенийВТаблицуЗначений(Дерево, Таблица = Неопределено) Экспорт

Если Таблица = Неопределено Тогда
Таблица = Новый ТаблицаЗначений;

Для Каждого Колонка Из Дерево.Колонки Цикл
Таблица.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;

КонецЕсли;

Для Каждого СтрокаДерева Из Дерево.Строки Цикл
ЗаполнитьЗначенияСвойств(Таблица.Добавить(), СтрокаДерева);
ВыгрузитьДеревоЗначенийВТаблицуЗначений(СтрокаДерева, Таблица);
КонецЦикла;

Возврат Таблица;

КонецФункции

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Запросы
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Функция ПолучитьРеквизитыПоСсылкам(Знач МассивСсылок,Знач СтрокаРеквизитов,Знач СтрокаРеквизитов1 = Неопределено) Экспорт

ОдинРеквизит = Неопределено;
РеквизитИсточник = Неопределено;
ОднаСсылка = Неопределено;
ВторойУровень = Ложь;
МассивРеквизитов = СтрРазделить(СтрокаРеквизитов,",");

Если МассивРеквизитов.Количество() = 1 и СтрокаРеквизитов1 <> Неопределено Тогда
РеквизитИсточник = МассивРеквизитов[0];
МассивРеквизитов = СтрРазделить(СтрокаРеквизитов1,",");
ВторойУровень = Истина;
КонецЕсли;

Если ТипЗнч(МассивСсылок) <> Тип("Массив") Тогда
ОднаСсылка = МассивСсылок;
МассивСсылок = СоздатьМассив(МассивСсылок);
КонецЕсли;

Запрос = Новый Запрос;
ТекстЗапроса = "";
Номер = 0;

Для каждого Ссылка Из МассивСсылок Цикл
Номер = Номер+1;
ИмяТаблицы = Ссылка.Метаданные().ПолноеИмя();
ТекстЗапроса = ТекстЗапроса+"
|ВЫБРАТЬ ПЕРВЫЕ 1
| Таблица.Ссылка,";

Для каждого Реквизит Из МассивРеквизитов Цикл
ТекстЗапроса = ТекстЗапроса+"
| Таблица."+?(ВторойУровень,РеквизитИсточник+"."+Реквизит,Реквизит)+" КАК "+Реквизит+",";
КонецЦикла;

ТекстЗапроса = СтрОбрезатьСправа(ТекстЗапроса,1);
ТекстЗапроса = ТекстЗапроса+"
|ИЗ "+ИмяТаблицы+" КАК Таблица
|ГДЕ
| Таблица.Ссылка = &Ссылка"+Номер+";";
Запрос.УстановитьПараметр("Ссылка"+Номер,Ссылка);
КонецЦикла;

Запрос.Текст = ТекстЗапроса;
РезультатПакета = Запрос.ВыполнитьПакет();
СоответствиеРезультатов = Новый Соответствие;

Если МассивРеквизитов.Количество() = 1 Тогда
ОдинРеквизит = МассивРеквизитов[0];
КонецЕсли;

Для Индекс = 0 По Номер-1 Цикл
Выборка = РезультатПакета[Индекс].Выбрать();

Если Выборка.Следующий() Тогда
СоответствиеРезультатов.Вставить(Выборка.Ссылка,
?(ОдинРеквизит = Неопределено,ПолучитьСтруктуруПоКлючам(
?(СтрокаРеквизитов1 = Неопределено,СтрокаРеквизитов,СтрокаРеквизитов1),Выборка),Выборка[ОдинРеквизит]));
КонецЕсли;

КонецЦикла;

Если ОднаСсылка <> Неопределено Тогда
Возврат СоответствиеРезультатов[ОднаСсылка];
Иначе
Возврат СоответствиеРезультатов;
КонецЕсли;

КонецФункции

Функция ПолучитьЗаписиТаблицы(ПутьТаблицы,СтруктураОтбора,СтрокаРеквизитов = "Ссылка",КоличествоЗаписей = 0) Экспорт

Запрос = Новый Запрос;
ИмяТаблицы = СтрЗаменить(ПутьТаблицы,".","");
МассивРеквизитов = СтрРазделить(СтрокаРеквизитов,",");
БезРеквизитов = МассивРеквизитов.Количество() = 1;

ТекстЗапроса =
"ВЫБРАТЬ"+?(КоличествоЗаписей = 0,""," ПЕРВЫЕ "+Формат(КоличествоЗаписей,"ЧГ=0"));

Для каждого ЭлементМассива Из МассивРеквизитов Цикл
ТекстЗапроса = ТекстЗапроса+"
| "+ИмяТаблицы+"."+ЭлементМассива+",";
КонецЦикла;

ТекстЗапроса = СтрОбрезатьСправа(ТекстЗапроса,1);
ТекстЗапроса = ТекстЗапроса+"
|ИЗ "+ПутьТаблицы+" КАК "+ИмяТаблицы+"
|ГДЕ
| ИСТИНА";

Для каждого ЭлементСтруктуры Из СтруктураОтбора Цикл
Запрос.УстановитьПараметр(ЭлементСтруктуры.Ключ,ЭлементСтруктуры.Значение);
ТекстЗапроса = ТекстЗапроса+"
| И "+ИмяТаблицы+"."+ЭлементСтруктуры.Ключ+" В (&"+ЭлементСтруктуры.Ключ+")";
КонецЦикла;

Запрос.Текст = ТекстЗапроса;
Результат = Запрос.Выполнить();

Если КоличествоЗаписей = 1 Тогда
Выборка = Результат.Выбрать();

Если Выборка.Следующий() Тогда
Если БезРеквизитов Тогда
Возврат Выборка[МассивРеквизитов[0]]; //значение
Иначе
Возврат Выборка; //элемент выборки
КонецЕсли;
КонецЕсли;

ИначеЕсли БезРеквизитов Тогда
Возврат Результат.Выгрузить().ВыгрузитьКолонку(МассивРеквизитов[0]); //массив
Иначе
Возврат Результат.Выбрать(); //выборка
КонецЕсли;

КонецФункции // ()

#Область РаботаСОтчетами

Процедура СкомпоноватьОтчет(Объект,НаборДанных,ДокументРезультат,ДанныеРасшифровки) Экспорт
Настройки=Объект.КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета=Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки=КомпоновщикМакета.Выполнить(Объект.СхемаКомпоновкиДанных,Настройки,ДанныеРасшифровки);
ПроцессорКомпоновки=Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки,НаборДанных,ДанныеРасшифровки);
ПроцессорВывода=Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры

Процедура УстановитьПараметрОтчета(Настройки,ИмяПараметра,Значение) Экспорт
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(ИмяПараметра,Значение);
КонецПроцедуры

Процедура ПолучитьПараметрОтчета(Настройки,ИмяПараметра) Экспорт
Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных(ИмяПараметра));
КонецПроцедуры

#КонецОбласти

#КонецЕсли

#Область РаботаСПроизвольнымиКоллекциями

Функция ПолучитьЗначениеПоКлючу(Источник,Ключ,ТипЗначения = Неопределено) Экспорт

Значение = Неопределено;

Если Источник <> Неопределено Тогда
Приемник = Новый Структура(Ключ);
ЗаполнитьЗначенияСвойств(Приемник,Источник);
Значение = Приемник[Ключ];
КонецЕсли;

Если ТипЗначения <> Неопределено Тогда
ОписаниеТипов = Новый ОписаниеТипов(СоздатьМассив(ТипЗначения));
Значение = ОписаниеТипов.ПривестиЗначение(Значение);
КонецЕсли;

Возврат Значение;

КонецФункции

Процедура УстановитьЗначениеПоКлючу(Источник,Ключ,Значение) Экспорт

Если Источник <> Неопределено Тогда
Приемник = Новый Структура(Ключ);
ЗаполнитьЗначенияСвойств(Приемник,Источник);

Если Приемник[Ключ] <> Неопределено Тогда
Источник[Ключ] = Значение;
КонецЕсли;

КонецЕсли;

КонецПроцедуры

Функция ПроверитьЗаполнениеРеквизитов(Источник,СтрокаРеквизитов,
ПолнаяПроверка = Истина,
ФормироватьСообщение = Истина,
ВыводитьСообщение = Истина,
ВызовИсключения = Ложь) Экспорт

СтруктураВозврата = Новый Структура;
МассивОшибок = Новый Массив;
МассивКлючей = СтрРазделить(СтрокаРеквизитов,",",Ложь);
ТекстСообщения = "";

Для каждого Ключ Из МассивКлючей Цикл
Если не ЗначениеЗаполнено(Источник[Ключ]) Тогда
МассивОшибок.Добавить(Ключ);

Если не ПолнаяПроверка Тогда
Прервать;
КонецЕсли;

КонецЕсли;
КонецЦикла;

Если МассивОшибок.Количество() > 0 Тогда

Если ФормироватьСообщение Тогда
ТекстСообщения = "Ошибка! Не заполнены значения реквизитов: "+СтрСоединить(МассивОшибок,", ")+".";

Если ВыводитьСообщение и не ВызовИсключения Тогда
Сообщить(ТекстСообщения);
КонецЕсли;

КонецЕсли;

Если ВызовИсключения Тогда
ВызватьИсключение ТекстСообщения;
КонецЕсли;

КонецЕсли;

СтруктураВозврата.Вставить("МассивОшибок",МассивОшибок);
СтруктураВозврата.Вставить("ТекстСообщения",ТекстСообщения);
СтруктураВозврата.Вставить("РезультатПроверки",МассивОшибок.Количество() = 0);

Возврат СтруктураВозврата;

КонецФункции

Процедура ЗаполнитьЗначенияРеквизитов(Источник,СтрокаРеквизитов,Заполненные = Истина,Значение = Неопределено) Экспорт

МассивКлючей = СтрРазделить(СтрокаРеквизитов,",");

Для каждого Ключ Из МассивКлючей Цикл
Если не Заполненные или ЗначениеЗаполнено(Источник[Ключ]) Тогда
Источник[Ключ] = Значение;
КонецЕсли;
КонецЦикла;

КонецПроцедуры

#Если не (ТонкийКлиент или ВебКлиент) Тогда

Функция СоздатьКопиюОбъекта(Источник) Экспорт
Возврат ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Источник));
КонецФункции

Функция ИмяЭлементаПеречисления(ЭлементПеречисления) Экспорт

ИмяПеречисления = ЭлементПеречисления.Метаданные().Имя;
Возврат Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления[Перечисления[ИмяПеречисления].Индекс(ЭлементПеречисления)].Имя;

КонецФункции

#КонецЕсли

#КонецОбласти

#Если не (ТонкийКлиент или ВебКлиент) Тогда

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Работа с транзакциями
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Процедура ЗафиксироватьАктивнуюТранзакцию() Экспорт
Если ТранзакцияАктивна() Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
КонецПроцедуры

Процедура ОтменитьАктивнуюТранзакцию() Экспорт
Если ТранзакцияАктивна() Тогда
ОтменитьТранзакцию();
КонецЕсли;
КонецПроцедуры

Процедура ЗавершитьАктивнуюТранзакцию(Отказ) Экспорт

Если Отказ Тогда
ОтменитьАктивнуюТранзакцию();
Иначе
ЗафиксироватьАктивнуюТранзакцию();
КонецЕсли;

КонецПроцедуры

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Шифрование
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Функция ПолучитьЗашифрованныеДанные(ИдентификаторДанных,ДанныеШифрования,КлючШифрования) Экспорт

Попытка

Путь = КаталогВременныхФайлов()+""+ИдентификаторДанных;
ПутьФайла = Путь+".txt";
ПутьАрхива = Путь+".zip";
ЗаписьТекста = Новый ЗаписьТекста(ПутьФайла);
ЗаписьТекста.Записать(ДанныеШифрования);
ЗаписьТекста.Закрыть();
ЗаписьАрхива = Новый ЗаписьZipФайла(ПутьАрхива,КлючШифрования,,,,МетодШифрованияZIP.AES256);
ЗаписьАрхива.Добавить(ПутьФайла);
ЗаписьАрхива.Записать();
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьАрхива);
Возврат Новый ХранилищеЗначения(ДвоичныеДанные,Новый СжатиеДанных(9));

Исключение
Возврат Неопределено;
КонецПопытки;

КонецФункции

Функция ПолучитьРасшифрованныеДанные(ИдентификаторДанных,ХранилищеДанных,КлючШифрования) Экспорт

Попытка
КаталогСохранения = КаталогВременныхФайлов();
Путь = КаталогСохранения+""+ИдентификаторДанных;
ПутьАрхива = Путь+".zip";
ХранилищеДанных.Получить().Записать(ПутьАрхива);
ЧтениеАрхива = Новый ЧтениеZipФайла(ПутьАрхива,КлючШифрования);
ЭлементАрхива = ЧтениеАрхива.Элементы[0];
ЧтениеАрхива.Извлечь(ЭлементАрхива,КаталогСохранения);
ЧтениеАрхива.Закрыть();
ЧтениеТекста = Новый ЧтениеТекста(КаталогСохранения+""+ЭлементАрхива.Имя);
Данные = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();
Возврат Данные;

Исключение
Возврат Неопределено;
КонецПопытки;

КонецФункции

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Прочее
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Функция ПопыткаЗаписиОбъекта(Объект,ТекстОшибки = "",
ВключатьОписаниеОшибки = Ложь,
ВыводитьСообщение = Ложь,
Статус = Неопределено,
ПредставлениеМетода = Неопределено,
ТекстОшибок = Неопределено,
Отказ = Ложь) Экспорт

Если не ЗначениеЗаполнено(ПредставлениеМетода) Тогда
ПредставлениеМетода = "Записать()";
КонецЕсли;

Попытка

Выполнить("Объект."+ПредставлениеМетода);

Исключение
Отказ = Истина;
ТекстСообщения = ТекстОшибки+?(ВключатьОписаниеОшибки," "+ОписаниеОшибки(),"");

Если ВыводитьСообщение Тогда
Сообщить(ТекстСообщения,Статус);
КонецЕсли;

Если ТекстОшибок <> Неопределено Тогда
ДобавитьСтрокуТекста(ТекстОшибок,ТекстСообщения);
КонецЕсли;

Возврат ТекстСообщения;
КонецПопытки;

КонецФункции

Функция ИнициализироватьCOMОбъект(Имя) Экспорт

Попытка
COMОбъект = Новый COMОбъект(Имя);
Возврат COMОбъект;
Исключение
Сообщить("Произошла ошибка инициализации "+Имя);
КонецПопытки;

КонецФункции // ()

#КонецЕсли

27 Comments

  1. lex27119

    Есть несколько весьма интересных функций

    Reply
  2. Famza

    Автор lex271, а в (1) lex27119 он же?

    Аналоги функций есть в типовых конфах, или наоборот

    Reply
  3. Infector
    Reply
  4. ruslan0277
    Reply
  5. TMV

    (3) Infector,

    с использованием заимствований из типовых конф в нетиповые встает вопрос авторских прав

    Довольно странное утверждение, ведь количество ключевых слов ограничено, а значит можно запросто своим умом составить такую же функцию и пр.. Да, и разве можно тогда пользоваться шаблонами?

    Reply
  6. Infector

    Не утверждаю, но смею предположить.

    Конечно, простые функции могут быть воспроизведены разными авторами в одинаковом содержании. С более сложными — нереально. Хотя бы стиль написания будет отличаться (я разделю 1 функцию на три мелких, кто-то не станет и т.д.)

    Reply
  7. kaging

    Можно думаю сюда прикрутить еще вот это

    Функция КратноеЧисло(ЧислоПроверки, КратноЧислу)
    
    РезультатДеления = ЧислоПроверки / КратноЧислу;
    Если Цел(РезультатДеления) =  Окр(РезультатДеления, 2) Тогда
    Возврат Истина;
    Иначе
    Возврат Ложь;
    КонецЕсли;
    
    КонецФункции
    

    Показать

    Или я ее просто не заметил у автора 🙁

    Reply
  8. Nebiros777

    Чтобы каждый раз не писать свои функции весьма полезно. Скорость разработки повышается, главное быстро найти нужный модуль. А так в закладки по-любому!

    Reply
  9. leasing

    (3) Infector, как защитить авторское право 1С на функцию ЗдравствуйМир() , если она оказалась в составе типовой, но её еще в школе ВСЕ проходили?

    Если любая из приведенных тут автором функций завтра окажется в составе типовой? Или уже есть там, но автор-то не был в курсе (не обязан он всякую муру на рынок выбрасываемую читать) и получил тот же результат?

    Я это все к тому, что если взять тридцать программистов и дать им одно и тоже задание, то обязательно получим энное количество совпадающих решений. Объектом авторского является произведение и его части. Чем крупнее произведение, тем больше вероятность, что там есть неоригинальные части, которые встречаются у других авторов. В музыке плагиатом не считается если совпало менее 4 нот подряд.

    Будем считать, хе-хе, если из конфигурации взято не более трех объектов, то это не считается нарушением авторских прав?

    Reply
  10. dolter

    Все не просмотрел — слишком много букв. Но покритиканствовать охота )

    Функция СтрОбрезатьСлева(Знач Строка,ЧислоСимволов) Экспорт
    
    Возврат Прав(Строка,СтрДлина(Строка)-ЧислоСимволов);
    
    КонецФункции

    Заменить на

    Функция СтрОбрезатьСлева(Знач Строка,ЧислоСимволов) Экспорт
    
    Возврат Сред(Строка,ЧислоСимволов + 1);
    
    КонецФункции
    Reply
  11. dolter

    В любом случае ПЛЮС!

    Но )… ПодставитьПараметрыВСтроку — заменить на:

    Функция ПодставитьПараметрыВСтроку(Знач СтрокаПодстановки, Параметры) Экспорт
    
    Для Каждого Элм Из Параметры Цикл
    СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, «%» + Элм.Ключ, ?(ТипЗнч(Элм.Значение) = Тип(«Строка»), Элм.Значение, СокрЛП(Элм.Значение)));
    КонецЦикла;
    
    Возврат СтрокаПодстановки;
    
    КонецФункции

    Показать

    Пример вызова:

    ПодставитьПараметрыВСтроку(СтрокаПодстановки, Новый Структура(«1,2,3,5», «123», Формат(ТекущаяДата(), «ДЛФ=D»), «321», 555));

    Плюсы: работает быстрее и не имеет ограничений по количеству параметров

    Reply
  12. Yashazz

    Всё, здесь изложенное, я сделал и начал использовать в 2009 году, задолго до появления похожих функционалов в типовых конфах. В том числе и (3) — быстрые переходы между разными коллекциями — давным-давно себе сделал. Вообще, удивлён подобными публикациями — это как выложить 2*2=4 и вдруг получить отчётливый интерес. Или современные одинэсники уже даже такие простейшие вещи полагают супер-наработкой?

    Reply
  13. alex271

    (12) Yashazz,

    Я думаю, тут дело не в том, что это супер-наработка, а в том, что многие программисты не хотят заниматься разработкой универсальных механизмов.

    Я на оригинальность не претендую, это написано в шапке публикации, но раз выложенные библиотеки вызвали оживленный интерес, значит в них есть потребность.

    Возможно, фирме 1С стоит подумать и добавить в технологическую платформу ряд универсальных функций, чтобы они сразу были под рукой у начинающих программистов.

    Reply
  14. BlackCors

    (13) alex271, да, это интересный вопрос. Может стоило поместить в платформу например ТЗ в ДЗ или что подобное? Почему на этапе планирования такие возможности не промелькнули ни в одной версии платформы, хотя бы в бета версиях?

    Reply
  15. BlackCors

    (12) Yashazz, + к тому что сказал alex271 у любого программиста в любом проекте ограниченно время, а объем задания не ограничен)) Заниматься постоянным изобретением велосипеда, нет никакого желания. И не только 1с-ков 😉 К тому же большинство задач (основная масса) которые ставят программистам 1с однотипны, уникальных задач куда более низкий процент, мое оценочное суждение 😉 Поэтому наработка подобной базы решений очень полезная вещь.

    Reply
  16. leasing

    (12) (12) Yashazz, как могло случиться такое невероятное событие, что вы написали и стали использовать в 2009 году все, что автор тут выложил в 2014?

    Reply
  17. Gureev

    (3) Infector, если целый модуль свистнуть — то да.

    использование отдельных процедур, особенно если они представляют из себя общий алгоритм, а не работу с конкретными объектами конкретной конфигурации

    — то нет. никаких авторских прав.

    Reply
  18. chmv

    Я бы включила гораздо больше стандартных функций в 1с (особенно при работе со строкой)

    Их очень мало, так что приходится дописывать в глобальных модулях

    Reply
  19. chmv

    Мне понравилась ИнвертироватьСтроку

    Reply
  20. Yashazz

    Насчёт отсутствия преобразований, зашитых в платформу — целиком согласен.

    Reply
  21. dyak84

    Автору спасибо очень интересно работает со строкой. Есть чему поучится. Так держать

    Reply
  22. nipil

    Забрал в копилку.

    Понравилась сама идея формирования публичной библиотеки необходимых функций.

    Желательно выработать и принять классификатор. (Группы, подгруппы и т.д.)

    Reply
  23. SemenovaMarinaV

    Для меня интересны функции работы со строкой. Полезно. Но лучше бы 1с расширило круг функций работы со строкой.

    Reply
  24. Andris_infostart

    (23) SemenovaMarinaV, http://v8.1c.ru/o7/201408str/index.htm

    тестовая 8.3.6 уже вышла.

    Reply
  25. alex271

    Обновил публикацию.

    Учел новые функции версии 8.3.6

    Reply
  26. KazanKokos

    А

     Возврат 

    в функциях уже необязателен?

    ////////////////////////////////////////////////////////////­///////////////////////////////////////////////////////////
    // Прочее
    ////////////////////////////////////////////////////////////­///////////////////////////////////////////////////////////
    
    Функция ПопыткаЗаписиОбъекта(Объект,ТекстОшибки = «»,
    ВключатьОписаниеОшибки = Ложь,
    ВыводитьСообщение = Ложь,
    Статус = Неопределено,
    ПредставлениеМетода = Неопределено,
    ТекстОшибок = Неопределено,
    Отказ = Ложь) Экспорт
    
    Если не ЗначениеЗаполнено(ПредставлениеМетода) Тогда
    ПредставлениеМетода = «Записать()»;
    КонецЕсли;
    
    Попытка
    
    Выполнить(«Объект.»+ПредставлениеМетода);
    
    Исключение
    Отказ = Истина;
    ТекстСообщения = ТекстОшибки+?(ВключатьОписаниеОшибки,» «+ОписаниеОшибки(),»»);
    
    Если ВыводитьСообщение Тогда
    Сообщить(ТекстСообщения,Статус);
    КонецЕсли;
    
    Если ТекстОшибок <> Неопределено Тогда
    ДобавитьСтрокуТекста(ТекстОшибок,ТекстСообщения);
    КонецЕсли;
    
    Возврат ТекстСообщения;
    КонецПопытки;
    
    КонецФункции
    
    Функция ИнициализироватьCOMОбъект(Имя) Экспорт
    
    Попытка
    COMОбъект = Новый COMОбъект(Имя);
    Возврат COMОбъект;
    Исключение
    Сообщить(«Произошла ошибка инициализации «+Имя);
    КонецПопытки;
    
    КонецФункции // ()

    Показать

    Reply
  27. dolter

    Да, собственно, возврат в функции действительно не обязателен — вернется значение Неопределено и все.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *