Вместо предисловия
Я знаю про CloudConf, и сервисы хранения кода, но на Инфостарте сижу каждый день, поэтому мне здесь удобнее. Да и возможность поделиться какими-то своими идеями, получив отклик, тоже интересна.
Код я оформляю в соответствии с соглашениями о написании кода.
1. Замер времени выполнения
// Описание разницы времени в формате "чч:мм:сс (ВсегоСекунд.ОстатокМиллисекунд сек.)"
//
// Параметры:
//  Старт - Число - результат значения работы функции "ТекущаяУниверсальнаяДатаВМиллисекундах()"
//  Финиш - Число - результат значения работы функции "ТекущаяУниверсальнаяДатаВМиллисекундах()"\r
//
// Возвращаемое значение:
//  Строка
//
Функция ОписаниеЗамераВремени(Старт, Финиш)
КолМлСекундЛог = Финиш - Старт;
КолСекундЛог = ЦЕЛ(КолМлСекундЛог / 1000);
КолМлСекунд = КолМлСекундЛог - КолСекундЛог;
ФорматКолМС = "" + КолМлСекунд;
ФорматКолМС = СтрЗаменить(ФорматКолМС, ",", "");
ФорматКолМС = СтрЗаменить(ФорматКолМС, " ", "");
ФорматКолМС = Лев(ФорматКолМС, 3);
Пока Прав(ФорматКолМС, 1) = "0" Цикл
ФорматКолМС = Сред(ФорматКолМС, 1, СтрДлина(ФорматКолМС)-1);
КонецЦикла;
ФорматСекунд = "" + КолСекундЛог + "." + ФорматКолМС;
чч = ЦЕЛ(КолСекундЛог/3600);
мм = ЦЕЛ((КолСекундЛог - чч*3600)/60);
сс =  КолСекундЛог - чч*3600 - мм*60;
СтрокаВремя = Формат(чч, "ЧЦ=2; ЧН=; ЧВН=") + ":" +
Формат(мм, "ЧЦ=2; ЧН=; ЧВН=") + ":" +
Формат(сс, "ЧЦ=2; ЧН=; ЧВН=") + " ("+ ФорматСекунд +" сек.)";
Возврат СтрокаВремя;
КонецФункции 
Пример использования:
 Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
//.. код
Финиш = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сообщить("Обработка завершена за " + ОписаниеЗамераВремени(Финиш, Старт));
// -> Обработка завершена за 00:00:03 (3.303 сек.)
2. Проверка значения на вхождение в некоторый интервал
// Проверка значения на вхождение в некоторый интервал
//
// Параметры:
//  Значение - Число, Дата - Проверяемое значение
//  НачалоИнтервала - Число, Дата
//  КонецИнтервала - Число, Дата
//  СтрогаяПроверка - Булево
//
// Возвращаемое значение:
//  Булево
//
Функция ЗначениеВИнтервале(Значение, НачалоИнтервала, КонецИнтервала, СтрогаяПроверка = Ложь)
Если СтрогаяПроверка Тогда
Возврат НачалоИнтервала < Значение И Значение < КонецИнтервала;
Иначе
Возврат НачалоИнтервала <= Значение И Значение <= КонецИнтервала;
КонецЕсли;
КонецФункции
Пример использования:
//.....
Если НЕ ЗначениеВИнтервале(ДатаПоказателя, НачалоПериода, КонецПериода) Тогда
Продолжить;
КонецЕсли;
//...
3. Разбиение строки на левую и правую часть
// Универсальная функция для парсинга строк
//
// Параметры:
//  ИсходнаяСтрока - Строка
//  СтрокаРазделитель - Строка
//  ОбрезатьПробелы - Булево
//
// Возвращаемое значение:
//  СтруктураЧастиСтроки - Структура
//   * Левая - Строка - Левая часть строки (до начала СтрокаРазделитель)
//   * Правая - Строка - Правая часть строки (после окончания СтрокаРазделитель)
//   * Разбито - Булево - флаг указывающий что в исходной строке есть СтрокаРазделитель
//
Функция РазбитьСтроку(ИсходнаяСтрока, СтрокаРазделитель, ОбрезатьПробелы = Истина)
поз = Найти(ИсходнаяСтрока, СтрокаРазделитель);
ДлинаРазделителя = СтрДлина(СтрокаРазделитель);
Разбито = поз > 0;
ЛеваяЧастьСтроки = Лев(ИсходнаяСтрока, поз - 1);
Если ОбрезатьПробелы Тогда
ЛеваяЧастьСтроки = СокрЛП(ЛеваяЧастьСтроки);
КонецЕсли;
ПраваяЧастьСтроки = Сред(ИсходнаяСтрока, поз + ДлинаРазделителя);
Если ОбрезатьПробелы Тогда
ПраваяЧастьСтроки = СокрЛП(ПраваяЧастьСтроки);
КонецЕсли;
СтруктураЧастиСтроки = Новый Структура("Левая, Правая, Разбито"
, ЛеваяЧастьСтроки
, ПраваяЧастьСтроки
, Разбито);
Возврат СтруктураЧастиСтроки;
КонецФункции
Пример использования:
//Парсинг строки вида "дд.мм.гггг":
Результат = Дата(1,1,1);
СтруктураЧастиСтроки = РазбитьСтроку(ЗначениеЯчейки, ".");
Если СтруктураЧастиСтроки.Разбито Тогда
ст_дд = Прав(СтруктураЧастиСтроки.Левая, 2);
чс_дд = Число(ст_дд);
СтруктураЧастиСтроки = РазбитьСтроку(СтруктураЧастиСтроки.Правая, ".");
Если СтруктураЧастиСтроки.Разбито Тогда
ст_мм = Прав(СтруктураЧастиСтроки.Левая, 2);
чс_мм = Число(ст_мм);
ст_гггг = Лев(СтруктураЧастиСтроки.Правая, 4);
чс_гггг = Число(ст_гггг);
Результат = Дата(чс_гггг, чс_мм,  чс_дд);
КонецЕсли;
КонецЕсли;
Возврат Результат;
4. Преобразование табличного документа в коллекцию
4.1 Табличный документ в таблицу значений (перебор)
В комментарии ниже дан более логичный код, с использованием построителя для этих целей (к сожалению, не пойму сейчас как ссылку на коммент дать). Оставил здесь эту функцию потому что мне иногда нужен перебор табличного документа, и ее использую качестве заготовки.
// Преобразование табличного документа в таблицу значений
//
// Параметры:
//  ТабДок - ТабличныйДокумент
//
// Возвращаемое значение:
//   ТаблицаЗначений
//
Функция ТабличныйДокументВТаблицуЗначений(ТабДок)
ТаблицаДанныеДокумента = Новый ТаблицаЗначений();
Для СчетчикКолонок = 1 По ТабДок.ШиринаТаблицы Цикл
ИмяКолонки = "_" + СчетчикКолонок;
ТаблицаДанныеДокумента.Колонки.Добавить(ИмяКолонки);
Для СчетчикСтрок = 1 По ТабДок.ВысотаТаблицы Цикл
ИндексСтроки = СчетчикСтрок - 1;
Если СчетчикКолонок = 1 Тогда
СтрокаТаблицы = ТаблицаДанныеДокумента.Добавить();
Иначе
СтрокаТаблицы = ТаблицаДанныеДокумента[ИндексСтроки];
КонецЕсли;
ТекущаяЯчейка = ТабДок.Область(СчетчикСтрок, СчетчикКолонок);
ЗначениеЯчейки = ТекущаяЯчейка.Текст;
СтрокаТаблицы[ИмяКолонки] = ЗначениеЯчейки;
КонецЦикла
КонецЦикла;
Возврат ТаблицаДанныеДокумента;
КонецФункции
4.2. Табличный документ в дерево значений
Решение задачи чтения иерархии табличного документа. Здесь стоит упомянуть статью Чтение группировок табличного документа:
- Сам алгоритм статьи не отрабатывает корректно, если есть несколько вложенных уровней группировок. Его исправили в последнем комментарии, но автор статью почему-то обновлять не стал.
- Предложенная там реализация отличается плохо читабельным кодом. Кроме этого задействовано три метода, в моем подходе — один. Подход к решению тоже разный: я использую видимость области строки, там используется парсинг таб. дока через документ DOM.
- При этом по скорости оба алгоритма показывают примерно одинаковое время
// Дерево значений по табличному документу, с аналогичной иерархией существующих группировок
//
// Параметры:
//  ТабДок - ТабличныйДокумент
//  СвойстваКолонок - ТаблицаЗначений
//  *Имя - Строка - Имя колонки дерева, в которую будут помещены данные области колонки табличного документа
//  *Номер - Число - Номер колонки в табличном документе
//  ВысотаШапки - Число - для отсечения незначащих строк
//  УдалятьФлаговыеКолонки - Булево - При анализе табличного документа в дерево добавляются служебные колонки
// "Начало" и "Конец", где сохраняются диапазоны группировки. Если Истина - то эти колонки при окончании
// алгоритма будут удалены.
//  ИсключатьПустыеСтроки - Булево - Если Истина, то строки в которых значения всех колонок пустые будут исключены
//
// Возвращаемое значение:
//  ДеревоЗначений
//
Функция ТабличныйДокументВДеревоЗначений(ТабДок, СвойстваКолонок, ВысотаШапки = 0, УдалятьФлаговыеКолонки = Истина, ИсключатьПустыеСтроки = Истина)
ДеревоДокумента = Новый ДеревоЗначений;
Для каждого ОписаниеКолонки Из СвойстваКолонок Цикл
ДеревоДокумента.Колонки.Добавить(ОписаниеКолонки.Имя);
КонецЦикла;
ДеревоДокумента.Колонки.Добавить("Начало");
ДеревоДокумента.Колонки.Добавить("Конец");
Кэш = Новый ТабличныйДокумент;
Кэш.Вывести(ТабДок);
Для сч = -Кэш.КоличествоУровнейГруппировокСтрок() По 0 Цикл
Кэш.ПоказатьУровеньГруппировокСтрок(-сч);
КонецЦикла;
ПройденныеСтроки = Новый Соответствие;
ПройденныеУровни = Новый Соответствие;
ПустыеСтроки = Новый Соответствие;
КоличествоУровней =Кэш.КоличествоУровнейГруппировокСтрок();
Для СчетчикУровня=1 По КоличествоУровней Цикл
ПройденныеУровни.Вставить(СчетчикУровня, Новый Массив);
Кэш.ПоказатьУровеньГруппировокСтрок(СчетчикУровня-1);
Для СчетчикСтрок=1 По Кэш.ВысотаТаблицы Цикл
Если СчетчикСтрок <= ВысотаШапки Тогда
Продолжить;
КонецЕсли;
Если ПройденныеСтроки.Получить(СчетчикСтрок) = Истина Тогда
Продолжить;
КонецЕсли;
Если ИсключатьПустыеСтроки Тогда
ЭтоПустаяСтрока = ПустыеСтроки.Получить(СчетчикСтрок);
Если ЭтоПустаяСтрока = Неопределено Тогда
ЭтоПустаяСтрока = Истина;
Для каждого ОписаниеКолонки Из СвойстваКолонок Цикл
ОбластьЯчейки = Кэш.Область(СчетчикСтрок, ОписаниеКолонки.Номер);
Если ЗначениеЗаполнено(ОбластьЯчейки.Текст) Тогда
ЭтоПустаяСтрока = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
ПустыеСтроки.Вставить(СчетчикСтрок, ЭтоПустаяСтрока);
КонецЕсли;
Если ЭтоПустаяСтрока Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
ИмяОбласти = "R" + Формат(СчетчикСтрок, "ЧГ=");
ОбластьСтроки = Кэш.Область(ИмяОбласти);
Если ОбластьСтроки.Видимость Тогда
Если СчетчикУровня = 1 Тогда
Родитель = ДеревоДокумента;
Иначе
МассивНомеровСтрокПредУровня = ПройденныеУровни.Получить(СчетчикУровня-1);
Для сч=-МассивНомеровСтрокПредУровня.ВГраница() По 0 Цикл
НомерСтрокиРодителя = МассивНомеровСтрокПредУровня[-сч];
Если НомерСтрокиРодителя < СчетчикСтрок Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Родитель = ДеревоДокумента.Строки.Найти(НомерСтрокиРодителя, "Начало", Истина);
КонецЕсли;
Узел = Родитель.Строки.Добавить();
Узел.Начало = СчетчикСтрок;
Для каждого ОписаниеКолонки Из СвойстваКолонок Цикл
ОбластьЯчейки = Кэш.Область(СчетчикСтрок, ОписаниеКолонки.Номер);
Узел[ОписаниеКолонки.Имя] = СокрЛП(ОбластьЯчейки.Текст);
КонецЦикла;
Если СчетчикУровня < КоличествоУровней Тогда
ПройденныеСтроки.Вставить(СчетчикСтрок, Истина);
МассивНомеровСтрокУровня = ПройденныеУровни.Получить(СчетчикУровня);
МассивНомеровСтрокУровня.Добавить(СчетчикСтрок);
КонецЕсли;
КонецЕсли;
Если Узел <> Неопределено Тогда
Узел.Конец = СчетчикСтрок;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если УдалятьФлаговыеКолонки Тогда
ДеревоДокумента.Колонки.Удалить("Начало");
ДеревоДокумента.Колонки.Удалить("Конец");
КонецЕсли;
Возврат ДеревоДокумента;
КонецФункции
5. Загрузка файлов: выбор на клиенте, обработка на сервере
Приведенный ниже код иллюстрирует работу с файлом типа "xlsx". Работа ведется из управляемой формы:
- 
пользователь выбирает файл; 
- 
файл помещается в временное хранилище, и становится доступен на сервере в виде двоичных данных; 
- 
производится запись двоичных данных в временный файл на сервере, с проверкой: если запись временного файла занимает более 30 секунд, пользователь получит уведомление о прерывании загрузки. 
// Выбор загружаемого файла, заполнение служебного реквизита формы "АдресФайлаВВременномХранилище"
//
// Возвращаемое значение:
//  Булево - Истина при успешном выборе файла
//
&НаКлиенте
Функция ПроизведенУспешныйВыборФайла()
ЭтаФорма.АдресФайлаВВременномХранилище = "";
#Если ВебКлиент Тогда
Если НЕ ПодключитьРасширениеРаботыСФайлами() Тогда
УстановитьРасширениеРаботыСФайлами();
ПодключитьРасширениеРаботыСФайлами();
КонецЕсли;
ПоместитьФайл(ЭтаФорма.АдресФайлаВВременномХранилище);
#Иначе
ДиалогФыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогФыбораФайла.Фильтр = "Таблица(*.xlsx)|*.xlsx";
ДиалогФыбораФайла.Заголовок = "Выберите файл";
ДиалогФыбораФайла.ПредварительныйПросмотр = Ложь;
ДиалогФыбораФайла.Расширение = "xlsx";
ДиалогФыбораФайла.МножественныйВыбор = Ложь;
Если ДиалогФыбораФайла.Выбрать() Тогда
ФайлЗагрузки = ДиалогФыбораФайла.ПолноеИмяФайла;
Иначе
Возврат Ложь;
КонецЕсли;
ЭтаФорма.АдресФайлаВВременномХранилище = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ДиалогФыбораФайла.ПолноеИмяФайла));
#КонецЕсли
Возврат НЕ ПустаяСтрока(ЭтаФорма.АдресФайлаВВременномХранилище);
КонецФункции
Пример использования:
//...
&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
Если ПроизведенУспешныйВыборФайла() Тогда
ВыполнитьЗагрузкуФайлаНаСервере();
КонецЕсли;
КонецПроцедуры
//...
&НаСервере
Процедура ВыполнитьЗагрузкуФайлаНаСервере()
АдресВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
// Запись двоичных данных из вр. хранилища:
ДвДанные = ПолучитьИзВременногоХранилища(ЭтаФорма.АдресФайлаВВременномХранилище);
Если ЗаписьФайлаПроизошлаУспешно(ДвДанные, АдресВременногоФайла) Тогда // см. ниже "Проверка записи файла
// обработка данных файла...
Иначе
ЛОГ("загрузка прервана на сервере - файл """+ АдресВременногоФайла +""" не обнаружен...");
КонецЕсли;
КонецПроцедуры
//...
6. Попытка записи данных в файл с таймаутом на время записи
// Попытка записи данных в файл с таймаутом на время записи
//
// Параметры:
//  Источник - Произвольный объект 1С, поддерживающий запись в файл через метод "Записать" - например ДвоичныеДанные или ТекстовыйДокумент
//  АдресФайла - Строка
//  ОграничениеВремениЗаписи - Число, количество секунд в течение которого будет выполнятся проверка существования файла
//  КомандаЗаписи - Строка, для различных случаев сохранения файла, в алгоритме будет параметром метода "Выполнить"
//
// Возвращаемое значение:
//  Булево
//
Функция ЗаписьФайлаПроизошлаУспешно(Источник, АдресФайла, ОграничениеВремениЗаписи = 30, КомандаЗаписи = "")
Попытка
Если ПустаяСтрока(КомандаЗаписи) Тогда
Источник.Записать(АдресФайла);
Иначе
Выполнить(КомандаЗаписи);
КонецЕсли;
ТекДата = ТекущаяДата();
ПредСекунда = 0;
Пока Истина Цикл
КолСекунд = ТекущаяДата() - ТекДата;
ТекСекунда = КолСекунд;
Если ПредСекунда < ТекСекунда Тогда
// Раз в секунду - проверка существования записываемого файла
ЗаписываемыйФайл = Новый Файл(АдресФайла);
Если ЗаписываемыйФайл.Существует() Тогда
Возврат Истина;
КонецЕсли;
ПредСекунда = ТекСекунда;
КонецЕсли;
Если КолСекунд > ОграничениеВремениЗаписи Тогда
ВызватьИсключение "время записи файла превысило "+ ОграничениеВремениЗаписи +" секунд";
КонецЕсли;
КонецЦикла;
Исключение
Лог("неудачная попытка записи файла на сервере - " + ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
КонецФункции
Пример использования:
//...
ТекстXSD = ЭтотОбъект.ПолучитьМакет("МакетXSD");
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xsd");
// Запись xsd файла с проверкой по тайм-ауту
Если НЕ ЗаписьФайлаПроизошлаУспешно(ТекстXSD, ИмяВременногоФайла, 5) Тогда
Возврат;
КонецЕсли;
// Или, если нужна запись с параметром:
Если НЕ ЗаписьФайлаПроизошлаУспешно(ТекстXSD, ИмяВременногоФайла, 5, "Источник.Записать(АдресФайла, КодировкаТекста.UTF8);") Тогда
Возврат;
КонецЕсли;
//...
7. Проверка интернет-соединения (ping)
// Проверка доступности переданного узла с помощью команды ping
//
// Параметры:
//  АдресURL - пингуемый адрес
//
// Возвращаемое значение:
//  Булево
//
Функция Пинг(АдресURL = "")
Если ПустаяСтрока(АдресURL) Тогда
АдресURL = "www.ya.ru";
КонецЕсли;
objShell = Новый COMОбъект("WScript.Shell") ;
objScriptExec = objShell.Exec("ping.exe -n 1 " + АдресURL);
strPingResults = НРег(objScriptExec.StdOut.ReadAll());
ЕстьСоединение = Найти(strPingResults, "ttl=") > 0;
Возврат ЕстьСоединение;
КонецФункции
Пример использования:
//...
ЕстьСоединениеСИнтернетом = Пинг(); // По-умолчанию пингуется www.ya.ru
//... 
8. Быстрое описание типа
// Упрощенный конструктор описания типа
//
// Параметры:
//  ИмяТипа - Строка, Массив элементов типа "Тип" - первый параметр конструктора ОписаниеТипов()
//  п1 - Произвольный, первый параметр квалификатора
//  п2 - Произвольный, второй параметр квалификатора
//  п3 - Произвольный, третий параметр квалификатора
//
// Возвращаемое значение:
//  ОписаниеТипов
//
Функция ОписаниеТипа(ИмяТипа, п1 = Неопределено, п2 = Неопределено, п3 = Неопределено)
Перем Результат;
Если ИмяТипа = "Строка" Тогда
п1 = ?(п1 = Неопределено, 0, п1);
Если п2 = Неопределено Тогда
п2 = ДопустимаяДлина.Переменная;
КонецЕсли;
КвалСтроки = Новый КвалификаторыСтроки(п1, п2);
Результат = Новый ОписаниеТипов(ИмяТипа,,,,КвалСтроки);
ИначеЕсли ИмяТипа = "Число" Тогда
п1 = ?(п1 = Неопределено, 0, п1);
п2 = ?(п2 = Неопределено, 0, п2);
Если п3 = Неопределено Тогда
п3 = ДопустимыйЗнак.Любой;
КонецЕсли;
КвалЧисла = Новый КвалификаторыЧисла(п1, п2, п3);
Результат = Новый ОписаниеТипов(ИмяТипа,,,КвалЧисла);
ИначеЕсли ИмяТипа = "Дата" Тогда
Если п1 = Неопределено Тогда
п1 = ЧастиДаты.ДатаВремя;
КонецЕсли;
КвалДаты = Новый КвалификаторыДаты(п1);
Результат = Новый ОписаниеТипов(ИмяТипа,,,,,КвалДаты);
Иначе
Результат = Новый ОписаниеТипов(ИмяТипа);
КонецЕсли;
Возврат Результат;
КонецФункции
Пример использования:
//...
Функция НоваяТаблицаОписанияОпераций()
тз = Новый ТаблицаЗначений;
тз.Колонки.Добавить("Сумма"         , ОписаниеТипа("Число", 15, 2));
тз.Колонки.Вставить("Описание"      , ОписаниеТипа("Строка", 100));
тз.Колонки.Вставить("ДатаОперации"  , ОписаниеТипа("Дата"));
МассивТипов = Новый Массив();
МассивТипов.Добавить(Тип("ДокументСсылка.Встреча"));
МассивТипов.Добавить(Тип("ДокументСсылка.ЗапланированноеВзаимодействие"));
тз.Колонки.Вставить("Событие"       , ОписаниеТипа(МассивТипов));
тз.Колонки.Вставить("Ответственный" , ОписаниеТипа("СправочникСсылка.Пользователи"));
Возврат тз;
КонецФункции
//... 
9. Шаблон чтения Excell через ADO
    ADODBConnection = Новый COMОбъект("ADODB.Connection");
ADODBConnection.Provider = "Microsoft.ACE.OLEDB.12.0";
ADODBConnection.Properties("Data Source").Value = СокрЛП(ЭтотОбъект.ПутьКФайлу);
ADODBConnection.Properties("Extended Properties").Value = "Excel 12.0;HDR=Yes;IMEX=1";
ADODBConnection.Open();
//  Получить список имен листов:
//    ADODBRecordset = Новый COMОбъект("ADODB.Recordset");
//    ADODBRecordset = ADODBConnection.OpenSchema(20);
//    СписокЛистов = Новый СписокЗначений;
//    Пока НЕ ADODBRecordset.EOF Цикл
//        ИмяЛиста = ADODBRecordset.Fields("TABLE_NAME").Value;
//        Если Найти(ИмяЛиста, "_xlnm#_FilterDatabase") = 0 Тогда
//            СписокЛистов.Добавить(ИмяЛиста);
//        КонецЕсли;
//        ADODBRecordset.MoveNext();
//    КонецЦикла;
//    ADODBRecordset.Close();
//    СписокЛистов.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
//    ИмяЛиста = СписокЛистов[0].Значение;
ТекстЗапроса = "SELECT * FROM [" + ЭтотОбъект.ИмяЛиста + "$]";
ADODBRecordset = Новый COMОбъект("ADODB.Recordset");
ADODBRecordset.Open(ТекстЗапроса, ADODBConnection);
КолвоКолонокExcel = ADODBRecordset.Fields.Count;
СчетчикСтрок = 1;
Пока ADODBRecordset.EOF() = 0 Цикл
Для СчетчикКолонок = 1 ПО КолвоКолонокExcel Цикл
Поле = ADODBRecordset.Fields.Item(СчетчикКолонок - 1);
Если Поле.ActualSize = 0 Тогда// Пустое поле EXCEL.
Продолжить;
КонецЕсли;
ЗначениеЯчейки = Поле.Value;
// Обработка значения ячейки
КонецЦикла;
ADODBRecordset.MoveNext();   // Следующая строка.
СчетчикСтрок = СчетчикСтрок + 1;
КонецЦикла;
ADODBConnection.Close();
ADODBRecordset = Неопределено;
ADODBConnection = Неопределено;   
10. Объединение ячеек шапки табличного документа с повторяющимся текстом
Этот метод служит для решения частной задачи отображения группировок колонок в табличных документах, полученных с помощью СКД. Исходная идея вот здесь: СКД. Как объединить заголовки родительских группировок колонок в таблице, я лишь причесал код. Этот вариант не будет работать с уже объединенными ячейками. Может позже допилю, пока нет нужды. Как использовать: в СКД делаем одну группировку колонок, в которую добавлем необходимые поля. После вывода табличного документа на форму вызываем метод.
// Объединяет ячейки шапки табличного документа с повторяющимся текстом
// Служит для решения задачи отображения группировок колонок в табличных документах, полученных с помощью СКД
//
// Параметры:
//  ТабДок - ТабличныйДокумент
//  ВысотаШапки - Число, если не передана, высотой шапки считается высота фиксации таблицы
//
Процедура СвернутьЗаголовкиШапкиТабличногоДокумента(ТабДок, ВысотаШапки = 0)
ВысотаШапки = ?(ВысотаШапки = 0, ТабДок.ФиксацияСверху, ВысотаШапки);
НачалоШапки = ?(ТабДок.ФиксацияСлева = 0, 1, ТабДок.ФиксацияСлева);
ЭтоПервоеОбъединение = Истина;
Для СчетчикСтрок=1 По ВысотаШапки Цикл
НомерПервойКолонкиОбъединения = 0;
Для СчетчикКолонок=НачалоШапки По ТабДок.ШиринаТаблицы Цикл
ОбъединятьЯчейки = Ложь;
Ячейка = ТабДок.Область(СчетчикСтрок, СчетчикКолонок);
Если ПустаяСтрока(Ячейка.Текст) Тогда
Продолжить;
КонецЕсли;
ЯчейкаСлед = ТабДок.Область(СчетчикСтрок, СчетчикКолонок+1);
ОбъединятьЯчейки = Ячейка.Текст = ЯчейкаСлед.Текст;
Если ОбъединятьЯчейки Тогда
НомерПервойКолонкиОбъединения = ?(НомерПервойКолонкиОбъединения = 0, СчетчикКолонок, НомерПервойКолонкиОбъединения);
ИначеЕсли НомерПервойКолонкиОбъединения > 0 Тогда
ТекстЗаголовка = ТабДок.Область(СчетчикСтрок, СчетчикКолонок).Текст;
ОбъединяемаяОбласть = ТабДок.Область(СчетчикСтрок, НомерПервойКолонкиОбъединения, СчетчикСтрок, СчетчикКолонок);
ОбъединяемаяОбласть.Объединить();
ОбъединяемаяОбласть.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
ОбъединяемаяОбласть.Текст = ТекстЗаголовка;
НомерПервойКолонкиОбъединения = 0;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
11. Формирование идентификатора по строке
// Формирование идентификатора по правилам образования имен переменных 1С по входящей строке
// Пример "Статья возмещение НДС" => "СтатьяВозмещениеНДС"
//
// Параметры:
//  стр - Строка - от которой необходимо получить идентификатор
//
// Возвращаемое значение:
//  Строка
//
Функция ИдентификаторПоСтроке(ЗНАЧ стр)
    ДопустимыеСимволы = "ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁQWERTYUIOPASDFGHJKLZXCVBNM" + 
    "йцукенгшщзхъфывапролджэячсмитьбюёqwertyuiopasdfghjklzxcvbnm_ ";
    СимволыЦифр = "0987654321";
    ДопустимыеСимволы = СимволыЦифр + ДопустимыеСимволы;
    
    Пока Найти(стр, "  ") > 0 Цикл
        стр = СтрЗаменить(стр, "  ", " ");            
    КонецЦикла; 
    
    ДлинаСтроки = СтрДлина(стр);
    СледующаяЗаглавная = Истина;
    Идентификатор = "";
    Для сч=1 По ДлинаСтроки Цикл
        
        сим = Сред(стр, сч, 1);
        
        Если Найти(ДопустимыеСимволы, сим) = 0 Тогда
            сим = "_";           
        КонецЕсли; 
        
        Если сч = 1 И сим = "_" Тогда
            Продолжить;            
        КонецЕсли; 
                
        Если сим = " " Тогда
            СледующаяЗаглавная = Истина;
            Продолжить;
        КонецЕсли; 
        
        Если СледующаяЗаглавная Тогда
            СледующаяЗаглавная = Ложь;
            Сим = Врег(Сим);            
        КонецЕсли; 
        ЭтоЦифра = Найти(СимволыЦифр, сим) > 0;            
        Если сч = 1 И ЭтоЦифра Тогда
            сим = "_" + сим;                
        КонецЕсли;             
        Если ЭтоЦифра Тогда
            СледующаяЗаглавная = Истина;                
        КонецЕсли; 
        
        Идентификатор = Идентификатор + Сим;                
    КонецЦикла; 
        
    Возврат Идентификатор;
КонецФункции
12. Формирование представления по идентификатору
// Преобразование переданного идентификатора в представление
//
// Параметры:
//  Идентификатор - Строка - образованная по правилам формирования идентификаторов 1С
//
// Возвращаемое значение:
//  Строка - преобразованный идентификатор.
//   - Первая буква всегда заглавная
//   - Первое подчеркивание пропускается
//   - Прочие заглавные буквы преобразуются в нижний регистр, после вставляется пробел
//   - Между цифрой и буквой вставляется пробел, между подряд идущими цифрами пробелов нет
//   - Несколько сплошных подчеркиваний воспринимаются как один, превращаются в пробел
//   - В строке может присутствовать символ, отличный от допустимых в идентификаторе - не обрабатывается
//   - Учитывается капитель (аббревиатуры) и спецсимволы в капители
//
// Примеры:
//   "ЭтоДата23_05_06" -> "Это дата 23 05 06"
//   "Это____ПримерС_Подчеркиваниями" -> "Это пример с подчеркиваниями"
//   "это_ПримерС_ПервойНеЗаглавной" -> "Это пример с первой не заглавной"
//   "Это_ПримерС_НевернымИден???тификатором*" -> "Это пример с неверным иден???тификатором*"
//   "_Это_ПримерС_первымПодчеркиванием" -> "Это пример с первым подчеркиванием"
//   "Это_КАПИ_ТЕЛЬ" -> "Это КАПИТЕЛЬ"
//   "Это_КАПИ99ТЕЛЬ" -> "Это КАПИ 99 ТЕЛЬ"
//   "Это_КАПИ??ТЕЛЬ" -> "Это КАПИ??ТЕЛЬ"
//
Функция ИдентификаторВПредставление(Идентификатор) Экспорт
Цифры = "0123456789";
Алфавит = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
ИдентификаторКОбработке = СокрЛП(Идентификатор);
Пока Найти(ИдентификаторКОбработке, "__") Цикл
ИдентификаторКОбработке = СтрЗаменить(ИдентификаторКОбработке, "__", "_");
КонецЦикла;
Пока Лев(ИдентификаторКОбработке, 1) = "_" Цикл
ИдентификаторКОбработке = Сред(ИдентификаторКОбработке, 2);
КонецЦикла;
ПредыдущийЗнакЭтоПробел = Ложь;
ПредыдущийЗнакЭтоЦифра = Ложь;
ПредыдущийЗнакЭтоЗаглавная = Ложь;
ПредыдущийЗнакЭтоСпецСимвол = Ложь;
Слово = "";
Для сч=1 По СтрДлина(ИдентификаторКОбработке) Цикл
ДобавитьПробел = Ложь;
Сим = Сред(ИдентификаторКОбработке, сч, 1);
ВрегСим = Врег(Сим);
НрегСим = Нрег(Сим);
СимВСлово = Сим;
ЭтоНижнийСлэш = сим = "_";
ЭтоЦифра = Найти(Цифры, Сим) > 0;
ЭтоБуква = Найти(Алфавит, ВрегСим) > 0;
ЭтоПрочийЗнак = НЕ (ЭтоНижнийСлэш ИЛИ ЭтоЦифра);
ЭтоЗаглавная = (Сим = ВрегСим) И (Сим <> НрегСим);
Если сч=1 Тогда
СимВСлово = ВрегСим;
ИначеЕсли ЭтоЦифра И НЕ ПредыдущийЗнакЭтоЦифра Тогда
ДобавитьПробел = Истина;
ИначеЕсли ЭтоНижнийСлэш Тогда
ДобавитьПробел = Истина;
СимВСлово = "";
ИначеЕсли ЭтоПрочийЗнак И ЭтоЗаглавная И НЕ ПредыдущийЗнакЭтоЗаглавная И НЕ ПредыдущийЗнакЭтоСпецСимвол Тогда
ДобавитьПробел = Истина;
СимВСлово = НрегСим;
КонецЕсли;
ЭтоВторойСимволКапители = ЭтоЗаглавная И ПредыдущийЗнакЭтоЗаглавная;
Если ЭтоВторойСимволКапители Тогда
ПоследнийСимвол = Прав(Слово, 1);
Слово = Сред(Слово, 1, СтрДлина(Слово)-1) + ВРЕГ(ПоследнийСимвол);
КонецЕсли;
ДобавитьПробел = ДобавитьПробел И НЕ ПредыдущийЗнакЭтоПробел;
Если ДобавитьПробел Тогда
СимВСлово = " " + СимВСлово;
КонецЕсли;
Слово = Слово + СимВСлово;
ПредыдущийЗнакЭтоПробел = СимВСлово = " ";
ПредыдущийЗнакЭтоЦифра = ЭтоЦифра;
ПредыдущийЗнакЭтоЗаглавная = ЭтоЗаглавная;
ПредыдущийЗнакЭтоСпецСимвол = НЕ (ЭтоБуква ИЛИ ЭтоНижнийСлэш ИЛИ ЭтоЦифра);
КонецЦикла;
Возврат Слово;
КонецФункции 
13. Формирование структуры для первой (единственной) записи результата запроса
// Формирование структуры для первой (единственной) записи результата запроса
//
// Параметры:
//  РезультатЗапроса - РезультатЗапроса, источник данных
//
// Возвращаемое значение:
//  Структура - Набор ключей повторяет набор колонок результат запроса, значения заполняются
// значениями первой записи выборки
//
Функция РезультатЗапросаВСтруктуру(РезультатЗапроса) Экспорт
СтруктураРезультат = Новый Структура;
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
Для каждого Колонка Из РезультатЗапроса.Колонки Цикл
Если Выборка.Количество() = 0 Тогда
МассивТипов = Колонка.ТипЗначения.Типы();
ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(МассивТипов, Тип("Null"));
ОписаниеТиповБезNULL = Новый ОписаниеТипов(МассивТипов);
ЗначениеПоля = ОписаниеТиповБезNULL.ПривестиЗначение();
Иначе
ЗначениеПоля = Выборка[Колонка.Имя];
КонецЕсли;
СтруктураРезультат.Вставить(Колонка.Имя, ЗначениеПоля);
КонецЦикла;
Возврат СтруктураРезультат;
КонецФункции
Related Posts
 Получение логина и пароля техподдержки 1С из базы Получение логина и пароля техподдержки 1С из базы
 Класс для вывода отчета в Excel Класс для вывода отчета в Excel
 Счет-фактура для УПП Счет-фактура для УПП
 Библиотека классов для создания внешней компоненты 1С на C# Библиотека классов для создания внешней компоненты 1С на C#
 Акт об оказании услуг (со скидками) — внешняя печатная форма для Управление торговлей 11.1.10.86 Акт об оказании услуг (со скидками) — внешняя печатная форма для Управление торговлей 11.1.10.86
 Прайс-лист с артикулом в отдельной колонке Прайс-лист с артикулом в отдельной колонке
 
    
Замер времени можно сделать точнее:
ТекущаяУниверсальнаяДатаВМиллисекундах(). Функция появилась в каком-то релизе 8.3
вот держи в копилку, вместо своего замера
Показать
(1) Йожкин Кот, это поддерживается только с
(2) tireal, спасибо за комментарий. Но:
— свою функцию я могу использовать в любом релизе платформы. Да, я порой работаю с 8.1 — как ни странно оно еще есть.
— если мне когда-нибудь понадобится настолько низкоуровневое отслеживание выполнения алгоритма — я скорее воспользуюсь замером времени отладчика
— могу предположить что назначение использования вашей функции — тестирование скорости исполнения алгоритма (т. е. она для этой цели писалась); моей — просто замер времени работы для сообщения/ помещения в лог — секунды вполне устраивают
Останусь при своем, но буду знать и о таком варианте, еще раз спасибо.
вместо Функция РазбитьСтроку(стр, сим)
можно вполне использовать СтрРазделить()
(4) androgin, Во-первых назначение СтрРазделить() и моей РазбитьСтроку() — разное. От слова совсем. Во-вторых СтрРазделить() — это начиная с .
(3) посмотри как сделано в ИР и универсальном отчете (от alexk-is), там есть до миллиекунд.
Показать
По поводу разделения строки — держи в копилку:
Показать
Если заранее известно, что строка не содержит символов перевода строки, то можно пользоваться стандартным:
(3)
Смешно. Вы думаете всякие извращения с джаваскриптами и т.п. появились потому что ни кто не додумался время выполнения в отладчике смотреть?!
Спасибо любимой 1С, они хоть от необходимости использовать внешние скрипты избавили, добавив в платформу функцию
А для старых версий платформы остается только замерять время выполнения при помощи внешних средств, например джава-скрипта.
(6) Знаю я об этих фишках, спасибо. Функция «ИзвлечьСлово» — не учитывает что символа может и не быть. И режет исходную строку. Как-раз чтобы этого избежать я наваял сп_РазбитьСтроку() — ее конечно не стоит применять на большом массиве данных, но для чтения небольших листов Excell — самое оно.
(7) h00k, почитайте внимательнее мой комментарий в (3) . И да, мне удобнее воспользоваться замером времени, чем вставлять в конфу отладочную печать. Не могу вспомнить случая, когда я не мог без этого обойтись. Может опыта еще маловато)
Имхо, все извращения с получением настолько точного времени — связаны с необходимостью отслеживать СКОРОСТЬ, а не ВРЕМЯ выполнения алгоритма. Разница трудноуловима, но она есть. Мне не надо с точностью до миллисекунды знать сколько времени проводился массив документов — 20 мин меня вполне устроит. Но если я тестирую напр. как быстрее создавать таблицу значений — тут нужны миллисекунды. Просто для универсальности функция замера обычно реализуется наиболее детализированно — т.е. через тот-же ява-скрипт. Ну а мне как-то не нужно было. Если понадобится — возьму из (6).
Загрузка файлов: выбор на клиенте, обработка на сервере
На веб клиенте давно не работает. Проблема всплывающих окон в браузерах. На последних релизах платформы не тестировал, но подозреваю что не исправили.
(9) mars207, тестировал на 8.3.5 — у меня работает. чяднт?
(9) mars207, все прекрасно работает
(5) уже давно все типовые версии требуют 8.3.6.2094 как минимальную
Странно, у меня половина типовых на 8.2.14.540, а еще половина на 7.7.027
(12) androgin, далеко не все используют исключительно типовые, и далеко не все еще перешли на новые конфы с УФ и БСП. Я уже писал в (3) что и с 8.1 иногда работаю.
(15) androgin,
Вы можете ошибаться… собственное развитие и вынужденная работа со старыми версиями конфигураций в учетных системах заказчика/ работодателя — в большинстве случаев ни как не связаны.
Переход предприятия на новую систему учета/ платформу — это достаточно дорогое удовольствие, и только из-за желания программиста работать с новыми версиями платформ/ конфигураций ни кто, в здравом уме, переходить не будет.
(15) androgin, не понимаю сути претензий. И с чего вы решили что я где-то там «торможусь»?.. Я подписан на рассылку, просматриваю ИТС, мониторю зазеркалье () работаю в основном на 8.3.6. И абсолютно солидарен с вами что в 1С сидят не дураки. Я только не понимаю, к чему это было сказано) Лучше перечитайте (5), попробуйте вникнуть в назначение сп_РазбитьСтроку() и понять таки что СтрРазделитьСтроку() в ее контексте в принципе не нужна. Я наверное сам дал еды троллю — лишним было писать «Во-вторых СтрРазделить() — это начиная с 8.3.6.1977».
> Преобразование табличного документа в таблицу значений
Вот это вроде с давних времен работает
Спасибо за статью. Иногда стоит вылезти из своего болота и посмотреть как люди делают :))))) +1
Про замеры времени. Написал пару процедур — засечь время и показать время замера (+ 2 вспомогательные). Недостаток — в многопотоке некорректно работает. А так, удобненько.
Показать
(18) А у меня еще дополнено
Я конечно все понимаю но раз вы пишите
Еще раз прочитайте эту часть
Мне кажется вы не правильно поняли блок как не надо делать
(22)
Какой участок кода навел вас на эту мысль?
Мир этому дому! Всегда приятно ознакомиться с чьим то опытом, и не менее приятна дискуссия по его обсуждению, где рождается если не истина, то разные варианты решения. Порой фраза в таком обсуждении рождает новые идеи даже не связанные, с текущей темой.
Функция ИдентификаторПоСтроке соответствует алгоритму платформы?
(25)
Специально не тестил, свое предназначение выполняет; вообще, должна. Возможно в регистрах символов будет различие, но т.к не имею кода платформы на руках 100% гарантии дать не могу)
(27) Решать задачи через попытку там где можно ее не использовать — очень плохой тон.
(28) Эту фразу вы вычитали в «умных» книжках? Корректная работа с СУБД при записи данных идет через попытку. Вы считаете, что использовать портянки кода там, где можно обойтись одной строкой, это хороший тон? Сначала доработайте алгоритм, чтобы он не считал «zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz» валидным ГУИДом, а потом еще проверьте его на быстродействие.
(29) Регулярные выражения. По быстродействию предлагаю провести сравнение. Было бы инетересно
(30) Замерил с помощью внешней компоненты /public/940766 на венде х64 — получился прирост в скорости в ~16 раз. Использовал шаблон «([0-9A-Fa-f]{8})-([0-9A-Fa-f]{4})-([0-9A-Fa-f]{4})-([0-9A-Fa-f]{4})-([0-9A-Fa-f]{4,12})»
(31) А в цифрах для каждого типа?
(29) я эту фразу пережил на собственном опыте. Попробуйте поотлаживаться когда есть пара сотен итераций цикла, и на каждой происходит выброс по попытке.
(33) Для этого давным-давно придумали замечательную вещь: Исключения.
(34) не понимаю, о чем вы, если можно — подробнее? з.ы. я не уточнил — имелась в виду отладка с включенным флагом «Остановка по ошибке».
Очень классно, спасибо!!! Такая шпаргалка в закладках, чтобы не ломать каждый раз голову. Коротко и ясно.
(27) Обнаружил недавно в БСП СтроковыеФункцииКлиентСервер.ЭтоУникальныйИдентификатор:
Показать