Книга знаний

1С:Предприятие

Библиотека продвинутых функцй

В этой статье я буду собирать полезные функции для 1С. Это даст программистам готовый, отлаженный функционал и избавит их от необходимости "изобретать велосипед". Вы можете также поучавствовать в составлении библиотеки, находя ошибки и добавляя свои полезные функции. Автор статьи: Гений 1С | Редакторы: Волшебник, BlackTiger,
Последняя редакция №8 от 18.05.07 | История
URL: http://kb.mista.ru/article.php?id=373

Библиотека продвинутых функций



Лучше использовать библиотеку целиком, тогда не надо выявлять, какая из функций использует другие функции.

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

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

История библиотеки записана в комментариях в конце кода.

Код библиотеки



[1С]

//Библиотека функций для продвинутой работы в 1С 80.  
//Версия от 20070518
//Создана: 20060922
//Создатель и ведущий библиотеки: Гений 1С
//Локальные переменные в функциях не обязательно объявляются
//Предполагается, что глобальные переменные именуются с использованием префикса
//Предполагается также, что эти функции располагаются в общих модулях, а не в модулях форм
//Префиксы всех функций начинаются на "об" или "pub" для англоязычных функций.
//Некоторые часто применяемые функции используются без префиксов
//
//Библиотеки расположены в алфавитном порядке
//На данный момент включены библиотеки:
//    Взаимодействие с пользователем
//    Внешние обработки
//    Встроенный язык
//    Даты
//    КлиентСервер - клиент-серверные функции
//    Коллекции
//    Контексты
//    Метаданные
//    Навигация
//    Нумераторы
//    ОЛЕ
//    Отчеты - функции для вывода отчетов
//    Отладка
//    Печать
//    Прикладные объекты - работа с прикладными объектами
//    Прочее
//    Строки
//    Сериализация - функции по сохраниению/восстанавлению значений
//    Типы
//    Уникальный идентификатор
//    Файлы
//    Формы
//    Хранилище значений

//Функции, которые используют методы/свойства клиента, заключаются в скобки #Если Клиент, причем эта конструкция должна располагаться внутри функции, т.к. каждая функция должна использоваться самостоятельно
//У каждой функции указано назначение параметров и список функций, которые вызываются непосредственно из нее.

//Для оценки состояния функции используются отдельные маркеры
//=отлажена - функция отлажена и протестирована
//=написать - функцию нужно написать
//=дописать - можно дописать функцию
//=неуни - неуниверсальная
//=отладить - нужно отладить

//Гарантируется обратная совместимость, если это правило нарушается, об этом сообщается в журнале библиотеки (внизу)

//Библиотека:ВЗАИМОДЕЙСТВИЕ С ПОЛЬЗОВАТЕЛЕМ

//Библиотека:ВНЕШНИЕ ОБРАБОТКИ
//Содержит функции для работы с внешними обработками

//Список функций, префиксы которых отличаются от ом и pub:
//ДУ,НовПрм,ПоказатьМакет,ПрекратитьФорму,Присвоить,Прм,Соо

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

//Библиотека:ВСТРОЕННЫЙ ЯЗЫК
//Усовершенствования встроенного языка

//Если делитель равен нулю, возвращает ноль
//Есть возможность округления
Функция обБезопасноеДеление(А,Б,Окр=Неопределено) Экспорт
   Рез=?(Б=0,0,А/Б);
   Если Окр<>Неопределено Тогда
       Рез=Окр(Рез, Окр);
   КонецЕсли;
   Возврат Рез;
КонецФункции

//Присваивает значение Б переменной А только если значение реально изменилось
//Удобно, когда нужно защититься от модифицированности
Функция обПрисвоитьБезопасно(А,Б) Экспорт
   Если А<>Б Тогда
       А=Б;
   КонецЕсли;
   Возврат А;
КонецФункции


//Библиотека:Даты, время
//Содержит функции для работы с датами

//Количество дней, прошедших после Дата2 до даты Дата1, т.е. Дата1-Дата2
Функция обРазностьДней(Дата1,Дата2) Экспорт
   Возврат (НачалоДня(Дата1)-НачалоДня(Дата2))/86400; //60*60*24
КонецФункции

//fixin 20070510
//Добавляет к дате определенное количество дней
//Возможны отрицательные значение - тогда не добавление, а отнимание
//Пример: 20070510 + 1 день = 20070511
Функция обДобавитьДни(Дата, КоличествоДней) Экспорт
   Возврат Дата+(КоличествоДней-1)*86400; //60*60*24
КонецФункции

//fixin 20070510
//Добавляет к дате определенное количество месяцев
//Возможны отрицательные значение - тогда не добавление, а отнимание
Функция обДобавитьМесяцы(Дата, КоличествоМесяцев) Экспорт
   Возврат ДобавитьМесяц(Дата, КоличествоМесяцев);
КонецФункции

//fixin 20070510
//Добавляет к дате определенное количество лет
//Возможны отрицательные значение - тогда не добавление, а отнимание
Функция обДобавитьГоды(Дата, КоличествоМесяцев) Экспорт
   Возврат ДобавитьМесяц(Дата, КоличествоМесяцев*12);
КонецФункции

//Задержка на указанное число секунд
Функция обЗадержка(Секунд) Экспорт
   Перем Начало, Конец;
   Начало=ТекущаяДата();
   Конец=Начало+Секунд;
   Пока ТекущаяДата()<=Конец Цикл
       обксОбработкаПрерыванияПользователя();
   КонецЦикла;
КонецФункции

//Библиотека:ЗНАЧЕНИЯ
//Работа со значениями


//Возвращает ссылку на объект или Неопределено, если объект не имеет ссылки
Функция обСсылка(Объект) Экспорт
КонецФункции

//Проверяет, является ли значение пустым
//Еще не реализована
Функция обПусто(Объект) Экспорт
КонецФункции

//Проверяет, что значение не заполнено
//Еще не реализована
Функция обНеПусто(Объект) Экспорт
   Возврат НЕ обПусто(Объект);
КонецФункции

//Получаем значения свойств
Функция обПолучитьЗначенияСвойств(Свойства, Объект)  Экспорт
   Стр=Новый Структура(Свойства);
   ЗаполнитьЗначенияСвойств(Стр, Объект);
   Возврат Стр;
КонецФункции


//Если объекту не назначена ссылка, назначает эту ссылку
Функция обДатьТочнуюСсылку(Объект) Экспорт
   Перем Ссылка, Вид;
   
   Ссылка=Объект.Ссылка;
   Если Ссылка.Пустая() Тогда
       Ссылка = Объект.ПолучитьСсылкуНового();
       Если Ссылка.Пустая() Тогда
           Вид=обМетаданные(Объект);
           Ссылка = обМенеджерОбъекта(Объект)[Вид].ПолучитьСсылку();
           Объект.УстановитьСсылкуНового(Ссылка);
       КонецЕсли;
   КонецЕсли;
   Возврат Ссылка;
КонецФункции


//Библиотека:КЛИЕНТ-СЕРВЕР
//КлиентСервер - клиент-серверные функции

//Подбиблиотека: КЛИЕНТ-СЕРВЕР::Конструкторы

//Подбиблиотека: КЛИЕНТ-СЕРВЕР::Прочие

//fixin 20070510
//Безопасное с точки клиент-сервера обращение к функции Состояние
Функция обксСостояние(С) Экспорт
#Если Клиент Тогда
   Состояние(С);
#КонецЕсли
КонецФункции

//fixin 20070510
//Безопасное с точки клиент-сервера обращение к функции ОбработкаПрерыванияПользователя
Функция обксОбработкаПрерыванияПользователя() Экспорт
   обксОбработкаПрерыванияПользователя();
КонецФункции

//fixin 20070510
//Безопасное с точки клиент-сервера обращение к функции Предупреждение
Функция обксПредупреждение(С,ТаймАут=Неопределено) Экспорт
#Если Клиент Тогда
   Предупреждение(С, ТаймАут);
#Иначе
   Сообщить(С, СтатусСообщения.Важное);
#КонецЕсли
КонецФункции


//Библиотека:КОЛЛЕКЦИИ
//Содержит функции для работы с коллекциями
//Коллекция элементов коллекции
Функция обРазмерКоллекции(К) Экспорт
КонецФункции

//Преобразует элементы коллекции в массив элементов коллекции, для дальнейшего перебора
//=написать
Функция обЭлементыКоллекции(К) Экспорт
КонецФункции

//Получение элемента коллекции по индексу
//=написать
Функция обЭлементКоллекцииПоИндексу(К, Индекс) Экспорт
КонецФункции
//Получение индекса элемента коллекции
//=написать
Функция обИндексЭлементаКоллекции(К, Эл) Экспорт
КонецФункции
//Добавление элемента в коллекцию
//=написать
Функция обДобавитьВКоллекцию(К, Эл) Экспорт
КонецФункции
//Вставка элемента в коллекцию
//=написать
Функция обВставитьВКоллекцию(К, Эл, Позиция) Экспорт
КонецФункции
//Сортировать коллекцию
//=написать
Функция обСортироватьКоллекцию(К, Порядок) Экспорт
КонецФункции
//Объединить коллекции, оставив различные элементы
//=написать
Функция обОбъединитьКоллекции(К1, К2, Новая=истина) Экспорт
КонецФункции
//Пересечь коллекции, оставив общие элементы
//=написать
Функция обПересечьКоллекции(К1, К2, Новая=истина) Экспорт
КонецФункции
//Соединить коллекции - для коллекций, допускающих неуникальные значения
//=написать
Функция обСоединитьКоллекции(К1, К2, Новая=истина) Экспорт
КонецФункции

//Создает копию структуры таблицы значений
//20070510
//Автор способа: Леха Дум
//Оформил: fixin
//=тестировать
Функция обСкопироватьКолонки(ТЗ) Экспорт
   Копия = Новый ТаблицаЗначений;
   Для Каждого Колонка Из ТЗ.Колонки Цикл
       Копия.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения, Колонка.Заголовок, Колонка.Ширина);
   КонецЦикла;
   Возврат Копия;
КонецФункции

//Подбиблиотека: КОЛЛЕКЦИИ::СПИСКИ ЗНАЧЕНИЙ
//Конструктор типка значений
//Если передается массив, составляет список из этого массива
//Если передаестся хранилище значений, извлекает значение и рекурсивно вызывает себя
//Если передается структура или соответствие, тогда значения списка берутся из значений коллекции,
//а представления из ключей (еще не оттестировано для этого случая)
//Если передается пустое значение, тогда возвращает пустой список
//Иначе возвращается список из одного значения

Функция обСписокЗначений(Значение) экспорт
   Если ТипЗнч(Значение)=Тип("Массив") Тогда
       С=Новый СписокЗначений();
       С.ЗагрузитьЗначения(Значение);
       Возврат С;
   КонецЕсли;
   
   Если ТипЗнч(Значение)=Тип("СписокЗначений") Тогда
       Возврат С;
   КонецЕсли;
   
   Если ТипЗнч(Значение)=Тип("ХранилищеЗначения") Тогда
       Возврат обСписокЗначений(Значение.Получить());
   КонецЕсли;
   
   Если ТипЗнч(Значение)=Тип("Структура") ИЛИ ТипЗнч(Значение)=Тип("Соответствие")  Тогда
       С=Новый СписокЗначений();
       Для Каждого Эл ИЗ Значение Цикл
           С.Добавить(Значение, Эл.Значение, Эл.Ключ);
       КонецЦикла;
       Возврат С;
   КонецЕсли;

   
   С=Новый СписокЗначений();
   Если НЕ ЗначениеНеЗаполнено(Значение) Тогда
       С.Добавить(Значение);
   КонецЕсли;
   
   Возврат С;
КонецФункции


//Функция для установки/сброса/инверсии всех пометок списка
//Список:СписокЗначений
//Зн:(истина,ложь,Неопределено) - истина - установить пометки, ложь - сбросить, Неопределено - инвертировать
//Отлажена: 20060922 Гений 1С
//=отлажена
Функция обУстановитьВсеПометкиСписка(Список, Зн) Экспорт
   Для Каждого Поз Из Список Цикл
       Если Зн=истина Тогда
           Поз.Пометка=Истина;
       ИначеЕсли Зн=ложь Тогда
           Поз.Пометка=ложь;
       Иначе //инверсия
           Поз.Пометка=Не Поз.Пометка;
       КонецЕсли;
   КонецЦикла;    
КонецФункции

//Функция для установки пометок списка-получателя согласно пометок списка-источника
//Источник:СписокЗначений - источник пометок
//Получатель:СписокЗначений - получатель пометок
//Возврат: Получатель
//Отлажена: 20060925 Гений 1С
//=отлажена
Функция    обУстановитьПометкуСпискаСогласноДругогоСписка(Получатель, Источник) Экспорт
   Для Каждого Эл из Источник Цикл
       Зн=Получатель.НайтиПоЗначению(Эл.Значение);
       Если Зн<>Неопределено Тогда
           Зн.Пометка=Эл.Пометка;
       КонецЕсли;
   КонецЦикла;
   Возврат Получатель;
КонецФункции

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

//В хвост списка К1 добавляется К2
//Не отлаживалась
//=отлажена
Функция обСклеитьСписки(К1, К2, флНовый=истина) Экспорт
   Если флНовый Тогда
       Получатель=К1.Скопировать();
   Иначе
       Получатель=К1;
   КонецЕсли;
   
   Для Каждого Эл ИЗ К2 Цикл
       Получатель.Добавить(Эл.Значение);
   КонецЦикла;
   
   Возврат Получатель;
КонецФункции

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

//Список, состоящий из элементов, которые есть в обоих списков
//=отлажена
Функция обСписокВСтроку(С,Разделитель=",") Экспорт
   Перем Р;
   Р="";
   Для Каждого Эл ИЗ С Цикл
       Р=Р+?(Р="","",Разделитель)+Строка(Эл.Значение);
   КонецЦикла;
   Возврат Р;
КонецФункции

//Конструктор списка значений из массива
//=отлажена
Функция обСписокЗначенийИзМассива(М) Экспорт
   Перем С;
   С=Новый СписокЗначений();
   С.ЗагрузитьЗначения(М);
   Возврат С;
КонецФункции

//20070517 fixin добавил
//Добавить в список, только если там нет этого значения
//Возвращает истину, если значение добавлено, иначе ложь
Функция обДобавитьУникальноВСписокЗначений(С, Значение, Представление=Неопределено, Пометка=Неопределено, Картинка=Неопределено) Экспорт
   Если С.НайтиПоЗначению(Значение)=Неопределено Тогда
       Эл=С.Добавить(Значение);
       Если Представление<>Неопределено Тогда
           Эл.Представление=Представление;
       КонецЕсли;
       Если Пометка<>Неопределено Тогда
           Эл.Пометка=Пометка;
       КонецЕсли;
       Если Картинка<>Неопределено Тогда
           Эл.Картинка=Картинка;
       КонецЕсли;
       
       Возврат истина;
   КонецЕсли;
   Возврат ложь;
КонецФункции


//Подбиблиотека: КОЛЛЕКЦИИ::КОНВЕРТАЦИЯ
//Конвертация одних коллекций в другие

Функция обСкопироватьМассив(М) Экспорт
   Рез=Новый Массив();
   Для Каждого Эл ИЗ М Цикл
       Рез.Вставить(Эл);
   КонецЦикла;
   Возврат Рез;
КонецФункции

Функция обОбъединитьМассивы(М1,М2, флНовый=ложь) Экспорт
   Если флНовый Тогда
       Получатель=обСкопироватьМассив(М1);
   Иначе
       Получатель=М1;
   КонецЕсли;
   
   Для Каждого Эл ИЗ М2 Цикл
       Получатель.Добавить(Эл);
   КонецЦикла;
   
   Возврат Получатель;
КонецФункции

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

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

//20070510
//Для представления коллекции
Функция обПредставлениеКоллекции(Зн, Разделитель=",") Экспорт
   Р="";
   Для Каждого Эл Из Зн Цикл
       Если ТипЗнч(Эл)=Тип("КлючИЗначение") Тогда
           ТекПредставление=Строка(Эл.Ключ)+"="+Строка(Эл.Значение);
       Иначе
           ТекПредставление=Строка(Эл);
       КонецЕсли;
       Р=Р+?(Р="","",Разделитель)+ТекПредставление;
   КонецЦикла;
   Возврат Р;
КонецФункции


//Библиотека:КОНТЕКСТЫ
//Содержит функции для работы с контекстами

//Позволяет из любого общего модуля получить переменную приложения
//Требует наличия в базе обработки "обПолучитьПеременнуюПриложения", без формы, модуль которой содержит код:
//Функция Получить(Имя) Экспорт
//Возврат Вычислить(Имя);
//КонецФункции
Функция обПолучитьПеременнуюПриложения(Имя) Экспорт
   Возврат Обработки.обПолучитьПеременнуюПриложения.Получить(Имя);
КонецФункции

//Функция определяет, определена ли в данном контексте функция
//Причем возвращает количество параметров функции
//Работаетс только для функций с 0-10 параметрами
//Нужно отладить
Функция обФункцияОпределена(ИмяФункции, КоличествоПараметров=Неопределено)
   Параметры="";
   Для Инд=0 По 10 Цикл
       Параметры=Параметры+?(Параметры="","",",")+"0";
       Код="Р=истина; "+ИмяФункции+"("+Параметры+");";
       Попытка
           Выполнить(Код);
           КоличествоПараметров=Инд;
           Возврат истина;
       Исключение
       КонецПопытки;
   КонецЦикла;
   Возврат ложь;
КонецФункции

//Библиотека:МЕТАДАННЫЕ
//Содержит функции для работы с метаданными

//Функция осуществляет более быстрый поиск метаданных, чем Объект.Метаданные()
Функция обМетаданные(Объект) Экспорт
   Если ТипЗнч(Объект)=Тип("Тип") Тогда
       Иск=Объект;
   Иначе
       Иск=ТипЗнч(Объект);
   КонецЕсли;
   Возврат Метаданные.НайтиПоТипу(Иск);
КонецФункции

//Функция проверяет, что ТипМастер является владельцем ТипРаб
//ТипМастер:Тип
//ТипРаб:Тип
//Результат:Булево
Функция обТипЯвляетсяВладельцемТипа(ТипМастер, ТипРаб) Экспорт
   МДРаб=обМетаданные(ТипРаб);
   МДМастер=обМетаданные(ТипМастер);
   Если МДРаб=Неопределено Тогда
       Возврат Ложь;
   КонецЕсли;
   
   Если обЭтоЗначениеМенеджера(ТипРаб, Справочники) Тогда //сыро
       Если МДРаб.Владельцы.Содержит(МДМастер) Тогда
           Возврат истина;
       КонецЕсли;
   Иначе
       Возврат ложь;
   КонецЕсли;
   Возврат ложь;
КонецФункции


//20070518 добавил fixin
//=отлажена 20070518
Функция обЕстьРеквизитШапки(Объект, ИмяРеквизита) Экспорт
   МД=обМетаданные(Объект);
   Если МД=Неопределено Тогда
       Возврат ложь;
   КонецЕсли;
   Возврат МД.Реквизиты.Найти(ИмяРеквизита)<>Неопределено;
КонецФункции

//20070518 добавил fixin
Функция обЕстьТабличнаяЧасть(Объект, ИмяТабличнойЧасти)
   МД=обМетаданные(Объект);
   Если МД=Неопределено Тогда
       Возврат ложь;
   КонецЕсли;
   Возврат МД.ТабличныеЧасти.Найти(ИмяТабличнойЧасти)<>Неопределено;
КонецФункции

//20070518 добавил fixin
Функция обЕстьРеквизитТабличнойЧасти(Объект, ИмяТабличнойЧасти, ИмяРеквизита) Экспорт
   МД=обМетаданные(ТипЗнч(Объект));
   Если МД=Неопределено Тогда
       Возврат ложь;
   КонецЕсли;
   Если обЕстьТабличнаяЧасть(Объект, ИмяТабличнойЧасти) Тогда
       Возврат МД.ТабличныеЧасти[ИмяТабличнойЧасти].Реквизиты.Найти(ИмяРеквизита)<>Неопределено;
   КонецЕсли;
КонецФункции

//Библиотека:НАВИГАЦИЯ
//Содержит функции для навигации по базе данных

//Библиотека:ОЛЕ
//Содержит функции для навигации по базе данных
//Добавление этой функции в базу позволяет выполнить любой код в базе.
//Т.к. к сожалению нет функции, которая была бы аналогом оператора Выполнить(Execute)
Function pubRunScript(AnyCode) Export
   try
       Execute (AnyCode);
       Возврат истина;
   except
       Возврат ОписаниеОшибки();
   endtry
EndFunction

//Библиотека:НУМЕРАТОРЫ
//Содержит функции для нумерации и нумераторов, а также для разных числовых кодировок

//Функция для преобразования иерархического кода в код сортировки с нужным числом разрядов.
//Пример 1.3.7 -> 001.003.007
//fixin 20070510

Функция обПреобразоватьИерКодВСортКод(Код, Разделители=".", Разрядность=3) Экспорт
   Перем СписокРазделителей, С, Р;
   
   СписокРазделителей=Новый СписокЗначений();
   Если ТипЗнч(Разделители)=Тип("Массив") Тогда
       СписокРазделителей.ЗагрузитьЗначения(Разделители);
   Иначе
       СписокРазделителей.Добавить(Разделители);
   КонецЕсли;
   
   С=СокрЛП(Строка(Код));
   Р="";
   ТекЧисло="";
   Для Инд=1 По СтрДлина(С)+1 Цикл
       Симв=Сред(С, Инд,1);
       ЭтоРазделитель=ложь;
       Если СписокРазделителей.НайтиПоЗначению(Симв)<>Неопределено ИЛИ Симв="" Тогда
           Если ТекЧисло<>"" Тогда
               ЭтоЧисло=ложь;
               Зн=обВЧисло(ТекЧисло,,ЭтоЧисло);
               Если ЭтоЧисло Тогда
                   ПредставлениеЗн=Формат(Зн,"ЧЦ="+Формат(Разрядность, "ЧГ=;")+"; ЧВН=; ЧГ=");
               Иначе
                   ПредставлениеЗн=обДополнитьСтрокуСимволами(СокрЛП(Строка(ТекЧисло)), Разрядность, "_", ложь);
               КонецЕсли;
               Р=Р+ПредставлениеЗн;
           КонецЕсли;
           ТекЧисло="";
       Иначе
           ТекЧисло=ТекЧисло+Симв;
       КонецЕсли;
   КонецЦикла;
   Возврат Р;
КонецФункции



//Библиотека:ОТЛАДКА
//Содержит функции, упрощающие отладку приложений

//Присваивает значению А значение Б
//Используется для изменения значения в табло и прерывания кода, путем присваивания переменной значения, которое вызовет ошибку
Функция Присвоить(А,Б) Экспорт
   А=Б;
   Возврат А;
КонецФункции

Функция ПрекратитьФорму(ЭтаФорма) Экспорт
   ЭтаФорма.Закрыть();
   Возврат истина;
КонецФункции

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

Функция Соо(Сообщение) Экспорт
   Сообщить(Сообщение);
КонецФункции

//20070510
//Для оперативного отображения макета
Функция ПоказатьМакет(ТД) Экспорт
   ТД.Показать();
КонецФункции


//Библиотека:ОТЧЕТЫ
//Содержит функции для вывода отчетов


Функция обВывестиДанныеВОтчет(П) Экспорт
   Перем Источник, Таб, Макет, спзГруппы, спзИтоги, ПараметрыПостроителя, ПостроительОтчета;
   Перем
       ПараметрыШапки, //Параметры, передаваемые в шапку
       ПараметрыПодвала,//Параметры, передаваемые в подвал
       ИмяШапки,    //Имя шапки в макете
       ИмяСтроки, //Имя строки в макете
       ИмяПодвала, //Имя подвала
       Показывать; //Показывать ли таблицу, по умолчанию истина

   П.Свойство("Источник", Источник);
   П.Свойство("Таб", Таб);
   П.Свойство("Макет", Макет);
   П.Свойство("Группы", спзГруппы);
   П.Свойство("Итоги", спзИтоги);
   П.Свойство("ПараметрыПостроителя", ПараметрыПостроителя);
   
   //Данные по умолчанию
   Если спзИтоги=Неопределено Тогда
       спзИтоги=Новый СписокЗначений();
   КонецЕсли;
   Если спзГруппы=Неопределено Тогда
       спзГруппы=Новый СписокЗначений();
   КонецЕсли;
   Если Таб=Неопределено Тогда
       Таб=Новый ТабличныйДокумент();
       П.Вставить("Таб", Таб);
   КонецЕсли;
   П.Свойство("ПараметрыШапки", ПараметрыШапки);
   П.Свойство("ПараметрыПодвала", ПараметрыПодвала);
   Если НЕ П.Свойство("ИмяШапки", ИмяШапки) Тогда
       П.Вставить("ИмяШапки", "Шапка");
   КонецЕсли;
   Если НЕ П.Свойство("ИмяСтроки", ИмяСтроки) Тогда
       П.Вставить("ИмяСтроки", "Строка");
   КонецЕсли;
   Если НЕ П.Свойство("ИмяПодвала", ИмяПодвала) Тогда
       П.Вставить("ИмяПодвала", "Подвал");
   КонецЕсли;
   Если НЕ П.Свойство("Показывать", Показывать) Тогда
       П.Вставить("Показывать", Истина);
   КонецЕсли;

   //Выводим шапку, если надо
   Если ИмяШапки<>Неопределено Тогда
       Шапка=Макет.ПолучитьОбласть(П.ИмяШапки);
       Если ПараметрыШапки<>Неопределено Тогда
           Шапка.Параметры.Заполнить(ПараметрыШапки);
       КонецЕсли;
       Таб.Вывести(Шапка);
   КонецЕсли;
   
   ПостроительОтчета=Новый ПостроительОтчета();
   Если ТипЗнч(Источник)=Тип("ОписаниеИсточникаДанных") Тогда
       ПостроительОтчета.ИсточникДанных=Источник;
   Иначе
       ПостроительОтчета.ИсточникДанных=Новый ОписаниеИсточникаДанных(Источник);
   КонецЕсли;
   обУстановитьИзмеренияПостроителяОтчета(ПостроительОтчета, спзГруппы);
   обУстановитьИтогиПостроителяОтчета(ПостроительОтчета, спзИтоги);

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

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

   Возврат ПостроительОтчета;
КонецФункции


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

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

Функция обСкорректироватьПорядокИзмеренийПостроителяОтчета(ПостроительОтчета, спзГруппы) Экспорт
   Перем Уровень, Эл, ИмяГруппировки, Элементы, Элемент;
   Уровень=0;
   Для Каждого Эл из спзГруппы Цикл
       ИмяГруппировки=Эл.Значение;
       Элементы=ПостроительОтчета.ИзмеренияСтроки;
       Элемент=Элементы.Найти(ИмяГруппировки);
       Если Элемент<>Неопределено Тогда
           Элементы.Сдвинуть(Элемент, Уровень-Элементы.Индекс(Элемент));
           Уровень=Уровень+1;
       КонецЕсли;
   КонецЦикла;
КонецФункции

//Заменяет названия уровней на конкретные названия полей
Функция обПреобразоватьМакетПостроителя(Макет, спзГруппы) Экспорт
   Перем Эл, Уровень, ИмяУровня, ИмяГруппы, НазваниеГруппы, сУровеньПуть;
   
   Для Каждого Эл ИЗ спзГруппы Цикл
       Уровень=спзГруппы.Индекс(Эл);
       ИмяУровня="Уровень"+Уровень;
       ИмяГруппы=Эл.Значение;
       НазваниеГруппы=Эл.Представление;
       обЗаменитьТекстМакета(Макет, "Параметр", ИмяУровня, ИмяГруппы);
       обЗаменитьТекстМакета(Макет, "Текст", "имя"+ИмяУровня, НазваниеГруппы);
       обПереименоватьОбластьМакета(Макет, ""+ИмяУровня, ИмяГруппы);
   КонецЦикла;
   
   сУровеньПуть="";
   Для Каждого Эл ИЗ спзГруппы Цикл
       сУровеньПуть=сУровеньПуть+?(сУровеньПуть="","",Символы.ПС)+Эл.Представление;
   КонецЦикла;
   обЗаменитьТекстМакета(Макет, "Текст", "УровеньПуть", сУровеньПуть);
   
   //Убираем ненужные группировки и реквизиты в колонках
   Уровень=спзГруппы.Количество();
   Пока Истина Цикл
       ИмяУровня="кУровень"+Уровень;
       Область=Макет.Области.Найти(ИмяУровня);
       Если Область=Неопределено Тогда
           Прервать;
       КонецЕсли;
       Макет.УдалитьОбласть(Область,ТипСмещенияТабличногоДокумента.ПоГоризонтали);
       Уровень=Уровень+1;
   КонецЦикла;

   Возврат Макет;
КонецФункции

Функция обЗаменитьТекстМакета(Макет, Параметр, сИсточник, сЗамена) Экспорт
   Перем Область, СледОбласть;
   СледОбласть=Неопределено;
   Пока (истина) Цикл
       Область=Макет.НайтиТекст(сИсточник,СледОбласть);
       Если Область=Неопределено Тогда
           Прервать;
       КонецЕсли;
       Если Область[Параметр]=сИсточник тогда
           Область[Параметр]=сЗамена;
       КонецЕсли;
       СледОбласть=Область;
   КонецЦикла;
КонецФункции

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


//Библиотека:ПЕЧАТЬ
//Содержит функции для распечатки значений
//Автор:Гений 1С 20070221
//Создана:Гений 1С 20070221
//Параметры:
//    ТЗ - таблица значений, выводимая в отчет
//    Макет - макет, который используется для вывода в отчет, может отсутствовать
//    Т - таблица, в которую выводить отчет, если не задана, создается
//    ПараметрыШапки - параметры, передаваемые в шапку
//    ПараметрыПодвала - параметры, передаваемые в подвал
//    ИмяШапки - имя шапки в макете, по умолчанию Шапка
//    ИмяСтроки - имя строки в макете, по умолчанию Строка
//    Показывать - показывать ли таблицу, по умолчанию истина
//    ИмяПодвала - имя подвала, по умолчанию Подвал
//    Показывать - показывать ли таблицу, по умолчанию истина
//    РасчитыватьИтоги - расчитывать ли итоги, по умолчанию истина
//Описание:
//    Сначала выводится шапка, затем строки, затем подвал.
//    Если указан флаг "Расчитывать итоги", то подвал заполняется итогами таблицы,
//    а затем из структуры "Параметры подвала".

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

   Для Каждого Стр ИЗ ТЗ Цикл
       Если ИмяСтроки<>Неопределено И Макет<>Неопределено Тогда
           Строка=Макет.ПолучитьОбласть(ИмяСтроки);
           Строка.Параметры.Заполнить(Стр);
           Т.Вывести(Строка);
       Иначе
           //выводим строки
           Для Каждого Кол ИЗ ТЗ.Колонки Цикл
               Т.Область(НачальнаяСтрока+1+ТЗ.Индекс(Стр), 1+ТЗ.Колонки.Индекс(Кол), НачальнаяСтрока+1+ТЗ.Индекс(Стр), 1+ТЗ.Колонки.Индекс(Кол)).Текст=Стр[Кол.Имя];
           КонецЦикла;
       КонецЕсли;
   КонецЦикла;
   
   Если ИмяПодвала<>Неопределено И Макет<>Неопределено Тогда
       Подвал=Макет.ПолучитьОбласть(ИмяПодвала);
       Если РасчитыватьИтоги=истина Тогда
           ПараметрыИтогов=Новый Структура();
           Для Каждого Кол ИЗ ТЗ.Колонки Цикл
               ПараметрыИтогов.Вставить(Кол.Имя, ТЗ.Итог(Кол.Имя));
           КонецЦикла;
           Подвал.Параметры.Заполнить(ПараметрыИтогов);
       КонецЕсли;
       
       Если ПараметрыПодвала<>Неопределено Тогда
           Подвал.Параметры.Заполнить(ПараметрыПодвала);
       КонецЕсли;
       Т.Вывести(Подвал);
   КонецЕсли;
   
   Если Показывать Тогда
       Т.Показать();
   КонецЕсли;
   Возврат Т;
КонецФункции

//Библиотека:ПРИКЛАДНЫЕ ОБЪЕКТЫ
//Работа с прикладными объектами
//Функция пока работает только со справочниками и документами.
//Но этого более чем достаточно.
//Результат возвращается в виде таблицы значений с колонками:
//    Реквизит - имя реквизита
//    ТабличнаяЧасть - имя табличной части
//    НомерСтроки - номер строки табличной части
//    Значение1, Значение2 - различающиеся значения реквизитов
//    Разница - есть ли различия.
//Указав параметр Разница=ложь, можно добиться, чтобы выдавался список всех реквизитов, даже одинаковых. Такая вариация может использоваться для разложения объекта в плоскую таблицу, если сравнивать его с самим собой.
//=неуни - можно сделать, чтобы работала не только со справочниками и документами
Функция обСравнитьДваОбъекта(О1, О2, Разница=истина) Экспорт
   Перем Т;
   Т=Новый ТаблицаЗначений();
   Т.Колонки.Добавить("Реквизит");
   Т.Колонки.Добавить("Значение1");
   Т.Колонки.Добавить("Значение2");
   Т.Колонки.Добавить("НомерСтроки");
   Т.Колонки.Добавить("ТабличнаяЧасть");
   Т.Колонки.Добавить("Разница");

   Если ТипЗнч(О1)<>ТипЗнч(О2) Тогда
       Возврат Неопределено;
   КонецЕсли;
   
   Ссылка1=О1.Ссылка;
   Ссылка2=О2.Ссылка;
   
   ЭтоСправочник=Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка1));
   ЭтоДокумент=Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка1));
   
   Если
       ЭтоДокумент ИЛИ ЭтоСправочник
   Тогда  
       МДО=Метаданные.НайтиПоТипу(ТипЗнч(Ссылка1));
       
       СписокРеквизитов=Новый Массив();
       Если ЭтоСправочник Тогда
           СписокРеквизитов.Добавить("Наименование");
           СписокРеквизитов.Добавить("ПометкаУдаления");
           СписокРеквизитов.Добавить("Код");
           Если МДО.Иерархический Тогда
               СписокРеквизитов.Добавить("Родитель");
               Если МДО.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
                   СписокРеквизитов.Добавить("ЭтоГруппа");
               КонецЕсли;
           КонецЕсли;
           Если МДО.Владельцы.Количество() <> 0 Тогда
               СписокРеквизитов.Добавить("Владелец");
           КонецЕсли;
       КонецЕсли;
       Если ЭтоДокумент Тогда
           СписокРеквизитов.Добавить("Дата");
           СписокРеквизитов.Добавить("Номер");
           СписокРеквизитов.Добавить("Проведен");
           СписокРеквизитов.Добавить("ПометкаУдаления");
       КонецЕсли;
       
       Для Каждого МДР ИЗ МДО.Реквизиты Цикл
           Реквизит=МДР.Имя;
           СписокРеквизитов.Добавить(Реквизит);
       КонецЦикла;
       Для Каждого Реквизит Из СписокРеквизитов Цикл
           Значение1=О1[Реквизит];
           Значение2=О2[Реквизит];
           Если Значение1<>Значение2 ИЛИ НЕ Разница Тогда
               Стр=Т.Добавить();            
               Стр.Реквизит=Реквизит;
               Стр.Значение1=Значение1;
               Стр.Значение2=Значение2;
               Стр.Разница=Значение1<>Значение2;
           КонецЕсли;
       КонецЦикла;
       
       Для Каждого МДТЧ ИЗ МДО.ТабличныеЧасти Цикл
           ИмяТЧ=МДТЧ.Имя;
           ТЧ1=О1[ИмяТЧ];
           ТЧ2=О2[ИмяТЧ];
           Для Инд=0 По Макс(ТЧ1.Количество()-1,ТЧ2.Количество()-1) Цикл
               Для Каждого МДРТЧ ИЗ МДТЧ.Реквизиты Цикл
                   Реквизит=МДРТЧ.Имя;
                   Если Инд>=ТЧ1.Количество() Тогда
                       Значение1=Неопределено;
                   Иначе
                       Значение1=ТЧ1[Инд][Реквизит];
                   КонецЕсли;
                   Если Инд>=ТЧ2.Количество() Тогда
                       Значение2=Неопределено;
                   Иначе
                       Значение2=ТЧ2[Инд][Реквизит];
                   КонецЕсли;
                   Если Значение1<>Значение2 ИЛИ НЕ Разница Тогда
                       Стр=Т.Добавить();            
                       Стр.Реквизит=Реквизит;
                       Стр.Значение1=Значение1;
                       Стр.Значение2=Значение2;
                       Стр.НомерСтроки=Инд;
                       Стр.ТабличнаяЧасть=ИмяТч;
                       Стр.Разница=Значение1<>Значение2;
                   КонецЕсли;
               КонецЦикла;
           КонецЦикла;
       КонецЦикла;
   КонецЕсли;
   
   Возврат Т;
   
КонецФункции

//20070516 fixin
//Записывает объект только если он модифицирован, удобно в паре с обПрисвоитьБезопасно.
//Неплохо бы сделать, чтобы можно было передавать параметры в функцию записать
//= отлажаена
Функция обЗаписатьОбъектЕслиМодифицирован(Объект) Экспорт
   Если Объект.Модифицированность() Тогда
       Объект.Записать();
   КонецЕсли;
КонецФункции


//Библиотека:ПРОЧЕЕ
//Содержит некоторые особенные функции

//// АЛЬТЕРНАТИВА СТЕКУ ////

//П, Стр - структуры
//П - родительская структура, Стр - дочерняя
Функция НовПрм(П, Стр) Экспорт
   Стр.Вставить("___Родитель", П);
   Возврат Стр;
КонецФункции

//Ищет свойство сначала в структуре П, а затем во всех ее родительских структурах
Функция Прм(П, Свойство) Экспорт
   Перем Р;
   Если П.Свойство(Свойство, Р) Тогда
       Возврат Р;
   КонецЕсли;
   
   Если П.Свойство("___Родитель", Р) Тогда
       Возврат Прм(Р, Свойство);
   КонецЕсли;
   
   Возврат Неопределено;
КонецФункции

//Библиотека:СЕРИАЛИЗАЦИЯ
//Прочие полезные функции с коллекциями

//Функция загружает весь макет в таблицу значений
//Первая строка содержит подписи колонок (должны быть правильные идентификаторы)
//Пустые строки (состоящией из пробелов, переводов строки и т.п.) заменяет на Неопределено
//Если в ячейке есть значение, в ячейку таблицы значений попадает именно это значение
//Отлажено:20060929
//Автор:Гений1С
Функция обМакетВТаблицуЗначений(Макет) Экспорт
   Перем ТЗ;
   
   ТЗ=Новый ТаблицаЗначений();
#Если Клиент Тогда
   //Считываем колонки
   Для Стр=1 По Макет.ВысотаТаблицы Цикл
       Если Стр>1 Тогда
           ТекСтр=ТЗ.Добавить();
       КонецЕсли;
       ПустаяСтрока=истина;
       Для Кол=1 По Макет.ШиринаТаблицы Цикл
           Яч=Макет.Область(Стр, Кол);
           Если Яч.СодержитЗначение Тогда
               Зн=Яч.Значение;
           Иначе
               Зн=Яч.Текст;
           КонецЕсли;
           Если ТипЗнч(Зн)=Тип("Строка") И ПустаяСтрока(Зн) Тогда
               Зн=Неопределено;
           КонецЕсли;
           
           //Добавляем колонку
           Если Стр=1 Тогда
               ТЗ.Колонки.Добавить(Зн);
           Иначе
               ТекСтр[Кол-1]=Зн;
           КонецЕсли;
       КонецЦикла;
   КонецЦикла;
   
#КонецЕсли
  Возврат ТЗ;
КонецФункции

//Библиотека:СТРОКИ
//Содержит функции для работы со строками

//Проверяет, является ли символ цифрой
Функция обЭтоЦифра(С) Экспорт
   Возврат Найти("0123456789", С)<>0;
КонецФункции

//Проверяет, является ли символ буквой
Функция обЭтоБуква(С) Экспорт
   Возврат обЭтоРусскаяБуква(С) ИЛИ обЭтоЛатинскаяБуква(С);
КонецФункции

Функция обЭтоРусскаяБуква(С) Экспорт
   Возврат Найти("АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЬЪЭЮЯ", ВРег(С))<>0;
КонецФункции

Функция обЭтоЛатинскаяБуква(С) Экспорт
   Возврат Найти("ABCDEFGHIJKLMNOPQRSTUVWXYZ", ВРег(С))<>0;
КонецФункции

Функция обЭтоИдентификатор(С) Экспорт
   Для Инд=1 По СтрДлина(С) Цикл
       Симв=Сред(С, Инд, 1);
       Если Инд=1 И обЭтоЦифра(Симв) Тогда
           Возврат ложь;
       ИначеЕсли НЕ (обЭтоБуква(Симв) ИЛИ Симв="_") Тогда
           Возврат ложь;
       КонецЕсли;
   КонецЦикла;
   Возврат истина;
КонецФункции

//20070510 fixin
//Дополняет строку С символами Символ до нужной длины Длина слева или справа, в зависимости от флага Справа
//Используется для форматирования строк
Функция обДополнитьСтрокуСимволами(С, Длина, Символ, Справа=истина)
   Перем Р;
   Р=С;
   Пока СтрДлина(Р)<Длина Цикл
       Если Справа Тогда
           Р=Р+Символ;
       Иначе
           Р=Символ+Р;
       КонецЕсли;
   КонецЦикла;
   Возврат Р;
КонецФункции


//Библиотека:ТИПЫ
//Содержит функции для работы с типами

//Проверяет, является ли объект ссылкой или экземпляром объекта менеджера
Функция обЭтоЗначениеМенеджера(Объект, Менеджер) Экспорт
   Возврат обЭтоСсылкаМенеджера(Объект, Менеджер) ИЛИ обЭтоЭкземплярМенеджера(Объект, Менеджер);
КонецФункции

//Проверяет, что объект - это экземпляр объекта менеджера
Функция обЭтоЭкземплярМенеджера(Объект, Менеджер) Экспорт
   Возврат обСодержитСсылку(Объект) И обЭтоСсылкаМенеджера(Объект.Ссылка, Менеджер) И Объект.Ссылка<>Объект;
КонецФункции

//Проверяет, что объект - это ссылка на объект менеджера
Функция обЭтоСсылкаМенеджера(Объект, Менеджер) Экспорт
   Возврат Менеджер.ТипВсеСсылки().СодержитТип(ТипЗнч(Объект)) И Объект<>Неопределено;
КонецФункции

//Проверяет, что значение Зн - это ссылка
//Написал, отладил 20070227 fixin
Функция обЭтоСсылка(Зн) экспорт
   Перем Ссылка;
   
   Ссылка=обИзвлечьСсылку(Зн);
   Возврат Зн=Ссылка и Ссылка<>Неопределено;
КонецФункции

//Проверяет, что значение Зн - это объект, который содержит ссылку
//Написал, отладил 20070227 fixin
Функция обСодержитСсылку(Зн) экспорт
   Перем Ссылка;
   Ссылка=обИзвлечьСсылку(Зн);
   Возврат Зн<>Ссылка и Ссылка<>Неопределено;
КонецФункции


//Проверяет, что значение Зн - это примитивный тип (простым перебором)
//Написал, отладил 20070227 fixin
Функция обЭтоПримитивныйТип(Зн) экспорт
   Возврат
       ТипЗнч(Зн)=Тип("Null") ИЛИ
       ТипЗнч(Зн)=Тип("Неопределено") ИЛИ
       ТипЗнч(Зн)=Тип("Число") ИЛИ
       ТипЗнч(Зн)=Тип("Строка") ИЛИ
       ТипЗнч(Зн)=Тип("Дата") ИЛИ
       ТипЗнч(Зн)=Тип("Булево") ИЛИ
       ТипЗнч(Зн)=Тип("Тип");
КонецФункции


//Извлекает ссылку из объекта или ссылки.
//Если извлечь ссылку невозможно, возвращает Неопределено.
//Работает корректно для всех типов, в том числе и для примитивных
//Написал, отладил 20070227 fixin
Функция обИзвлечьСсылку(Зн) экспорт
   Перем С;
   Если обЭтоПримитивныйТип(Зн) Тогда
       Возврат Неопределено;
   КонецЕсли;
   С=Новый Структура("Ссылка", Неопределено);
   ЗаполнитьЗначенияСвойств(С, Зн);
   Возврат С.Ссылка;
КонецФункции



//Проверяет, что это экземпляр прикладного объекта
Функция обЭтоЭкземпляр(Объект) Экспорт
   Возврат обСодержитСсылку(Объект) И Объект<>Объект.Ссылка;
КонецФункции

//Проверяет, что объект является менеджером
Функция обЭтоМенеджер(Объект) Экспорт
   СтруктураМенеджеров=обСтруктураМенеджеров();
   Для Каждого Эл Из СтруктураМенеджеров Цикл
       Если Эл.Значение=Объект Тогда
           Возврат Истина;
       КонецЕсли;
   КонецЦикла;
   Возврат Ложь;
КонецФункции

//Возвращает список всех менеджеров и соответствующих им названий метаданных
Функция обСтруктураМенеджеров() Экспорт
   Возврат Новый Структура(
   "
   |Справочники,
   |Документы,
   |Перечисления,
   |Константы,
   |БизнесПроцессы,
   |КритерииОтбора,
   |Последовательности,
   |ЖурналыДокументов,
   |Отчеты,
   |Обработки,
   |ПланыВидовХарактеристик,
   |ПланыСчетов,
   |ПланыВидовРасчета,
   |Задачи,
   |РегистрыСведений,
   |РегистрыНакопления,
   |РегистрыРасчета,
   |ПланыОбмена
   |",
   Справочники,
   Документы,
   Перечисления,
   Константы,
   БизнесПроцессы,
   КритерииОтбора,
   Последовательности,
   ЖурналыДокументов,
   Отчеты,
   Обработки,
   ПланыВидовХарактеристик,
   ПланыСчетов,
   ПланыВидовРасчета,
   Задачи,
   РегистрыСведений,
   РегистрыНакопления,
   РегистрыРасчета,
   ПланыОбмена
   );
КонецФункции

//Возвращает менеджер объекта, например для справочника возвращает Справочники
//Нужно дописать для всех прикладных объектов
//Отлажена: 20060922 Гений 1С
Функция обМенеджерОбъекта(Объект) Экспорт
   МД=обМетаданные(Объект);
   СтруктураМенеджеров=обСтруктураМенеджеров();
   Для Каждого Эл Из СтруктураМенеджеров Цикл
       Если Метаданные[Эл.Ключ].Содержит(МД) Тогда
           Возврат Эл.Значение;
       КонецЕсли;
   КонецЦикла;
   Возврат Неопределено;
КонецФункции



//20070209 fixin
//Добавлено, потому что в 1С нет нормальной функции преобразования числа в строку без региональных стандартов
//Как во всех нормальных языках программирования
Функция обЧислоВСтроку(Ч) Экспорт
   Возврат Формат(Ч, "ЧГ=");
КонецФункции

//fixin add 20070424
//Преобразует строку в число
//Если преобразовать невозможно, возвращает 0
//В переменной Р возвращает ту часть строки, которую можно распознать как число
//В переменную Ошибка возвращается флаг ошибки
Функция обВЧисло(С, Р=Неопределено, ЭтоЧисло=ложь) Экспорт
   Перем Симв;
   Р="";
   
   ЭтоЧисло=ложь;
   
   БылаТочка=ложь;
   БылЗнак=ложь;
   Для Инд=1 По СтрДлина(С) Цикл
       Симв=Сред(С, Инд,1);
       Если Симв=" " Тогда
           Продолжить;
       КонецЕсли;
       Если Симв="." ИЛИ Симв="," Тогда
           Если БылаТочка Тогда
               Возврат 0;
           КонецЕсли;
           Р=Р+".";
           БылаТочка=истина;
           Продолжить;
       КонецЕсли;
       Если Симв="+" ИЛИ Симв="-" Тогда
           Если БылЗнак ИЛИ Р<>"" Тогда
 

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика