Функция ВывестиДокументВордВМоксель(ИмяФайла, рСантиметр = 6.25, рШиринаСтраницы = 75, ФильтрТаблиц = "Условие=Истина") Экспорт // источник: https://infostart.ru/1c/articles/1499795/ комВорд = Неопределено; комДокумент = Неопределено; Попытка // Для пересчётов использовать комВорд.CentimetersToPoints(ЧислоСМ) и комВорд.PointsToCentimeters(ЧислоПунктов) // рСантиметр=6.25; // в средних символах шрифта (при необходимости пересчитывать по рДиапазон.CharacterWidth - ширина символов, константа WdCharacterWidth //рШиринаСтраницы=75; // эмпирически, довести до ума с учётом //сообщить("стран ширина "+стран.PageWidth+", высота "+стран.PageHeight); // в пунктах, работает // Типовые настройки документа Ворд: // 1.25 до номера (отступ первой строки) и 1.89 табуляция (до основного текста) // Размеры листа А4 в сантиметрах: 21х29.7 комВорд = Новый COMОбъект("Word.Application"); рПодтверждатьПреобразования = Истина; рТолькоЧтение = Истина; комДокумент = комВорд.Documents.Open(ИмяФайла, рПодтверждатьПреобразования, рТолькоЧтение); #Область Проверки комСтраница = комДокумент.PageSetup; Если комСтраница.TextColumns.Count > 1 Тогда Сообщить("Текущая версия не обрабатывает многоколонные документы!"); ЗакрытьДокумент(комДокумент); // без сохранения ЗакрытьВорд(комВорд); Возврат Неопределено; КонецЕсли; рШиринаСтраницыВорда = Окр(комВорд.PointsToCentimeters(комСтраница.PageWidth), 2); рВысотаСтраницыВорда = Окр(комВорд.PointsToCentimeters(комСтраница.PageHeight), 2); Если НЕ ((20 <= рШиринаСтраницыВорда И рШиринаСтраницыВорда <= 22) И (28 <= рВысотаСтраницыВорда И рВысотаСтраницыВорда <= 30)) Тогда Сообщить("Текущая версия не обрабатывает размеры страницы, отличающиеся от А4!"); ЗакрытьДокумент(комДокумент); // без сохранения ЗакрытьВорд(комВорд); Возврат Неопределено; КонецЕсли; #КонецОбласти // подготовка вывода таблиц мКомТаблиц = Новый Массив; всеТаблицы = Фильтр(ФильтрТаблиц, комДокумент.Tables); Для каждого комТаблица Из всеТаблицы Цикл мКомТаблиц.Добавить(Новый Структура("Начало,Конец,Таблица", комТаблица.Range.Start, комТаблица.Range.End, комТаблица)); КонецЦикла; #Область ПодготовкаВыводаНумерованныхСписков // можно, конечно, рСписок.ConvertNumbersToText(ТипНомера) - но это не лучший выход, и это изменение документа // соотПараграфовСписков = Новый Соответствие; Для каждого рСписок Из комДокумент.Lists Цикл // свойство комДокумент.Lists.Count ситуационно-зависимое, не применять! // рЛист.CountNumberedItems(); Для каждого рПараграфСписка Из рСписок.ListParagraphs Цикл рФорматСписка = рПараграфСписка.Range.ListFormat; рТипСписка = рФорматСписка.ListType; // WdListType Если рТипСписка = 0 ИЛИ рТипСписка = 2 ИЛИ рТипСписка = 6 Тогда // ненумерованные и bullet игнорируем Иначе // заниматься иерархией с проверкой погружения (рФорматСписка.ListLevelNumber) не будем, нам достаточно проверить так: рПредставлениеПункта = СокрЛП(рФорматСписка.ListString); // выравнивание смотрим по первой позиции уровней (хотя можно перебирать, смотреть по позиции или по NumberFormat) Попытка рВыравнивание = рФорматСписка.ListTemplate.ListLevels.Item(0).Alignment Исключение рВыравнивание = 0 КонецПопытки; // из первого уровня также можно брать NumberPosition - отступ,если будет надо; он в пунктах, поэтому тоже может потребоваться пересчёт! Если СтрРазделить(рПредставлениеПункта, ".", Ложь).Найти(рФорматСписка.ListValue) = 0 Тогда Сообщить("Внимание! Нарушение нумерации списка для " + рПредставлениеПункта + "!"); КонецЕсли; // фиксируем для дальнейшего вывода соотПараграфовСписков.Вставить(рПараграфСписка.Range.Start, Новый Структура("Номер,Выравнивание", рПредставлениеПункта, рВыравнивание)); КонецЕсли; КонецЦикла; КонецЦикла; #КонецОбласти // FitTextWidth для диапазонов НЕ используем, в т.ч. для комДокумент.Range() т = Новый ТабличныйДокумент; #Область ПодготовкаТабДокумента // устанавливаем ширины рабочих колонок А4 стлб = 1; Пока Истина Цикл т.Область(1, стлб, 1, стлб).ШиринаКолонки = Окр(рСантиметр / 4, 2); стлб = стлб + 1; Если т.ШиринаТаблицы > рШиринаСтраницы Тогда Прервать; КонецЕсли; КонецЦикла; #КонецОбласти #Область ВыводОсновныхДанных стрк = 1; рПравыйКрайнийСтолбец = т.ШиринаТаблицы; рИдётТаблица = Ложь; Для каждого рПараграф Из комДокумент.Paragraphs Цикл // к сожалению, рПараграф.ListNumberOriginal использовать ненадёнжно рДиапазон = рПараграф.Range; рТекстДиапазона = рДиапазон.Text; рНачалоДиапазона = рДиапазон.Start; рКонецДиапазона = рДиапазон.End; #Область ВыводПозицииНумерованногоСписка // использовать рДиапазон.ListFormat.ListLevelNumber и рДиапазон.ListFormat.ListValue не рекомендуется рПараграфСписка = соотПараграфовСписков.Получить(рНачалоДиапазона); Если рПараграфСписка = Неопределено Тогда рПредставлениеПункта = ""; рВыравнивание = 0; Иначе рПредставлениеПункта = СокрЛП(рПараграфСписка.Номер); рВыравнивание = рПараграфСписка.Выравнивание; КонецЕсли; Если ПустаяСтрока(рПредставлениеПункта) Тогда // нумерации списка нет рГраницаОбластиПараграфа = 1; Иначе // надо выводить № пункта списка рОбластьНомера = т.Область(стрк, 1, стрк, 4); рОбластьНомера.Объединить(); рОбластьНомера.Текст = рПредставлениеПункта; рОбластьНомера.Шрифт = ПостроитьШрифт(ВыборШрифта(рДиапазон)); // или рДиапазон.ListStyle.Font, если они разные рОбластьНомера.ГоризонтальноеПоложение = ПолучитьВыравнивание(рВыравнивание); рОбластьНомера.ВертикальноеПоложение = ВертикальноеПоложение.Верх; // по умолчанию рГраницаОбластиПараграфа = 5; КонецЕсли; #КонецОбласти комТаблица = Неопределено; Для каждого знч Из мКомТаблиц Цикл Если знч.Начало <= рНачалоДиапазона И рНачалоДиапазона <= знч.Конец И знч.Начало <= рКонецДиапазона И рКонецДиапазона <= знч.Конец Тогда // можно было бы рДиапазон.InRange(комТаблица.Range), но оно медленнее комТаблица = знч.Таблица; Прервать; КонецЕсли; КонецЦикла; Если комТаблица = Неопределено Тогда рИдётТаблица = Ложь; #Область ВыводОбычногоАбзаца // для параграфа и Диапазон.ParagraphFormat, при необходимости: // рПараграф.FirstLineIndent - Возвращает или устанавливает значение в пунктах для первой линии или отступа. // рПараграф.LeftIndent - Отступ слева в пунктах. // рПараграф.RightIndent - Отступ справа в пунктах. // рПараграф.LineSpacing - Междустрочный интервал. // рПараграф.PageSetup.PageWidth аналогично ширине документа в целом, можно не заморачиваться рОбластьПараграфа = т.Область(стрк, рГраницаОбластиПараграфа, стрк, рПравыйКрайнийСтолбец); рОбластьПараграфа.Объединить(); рОбластьПараграфа.Текст = рТекстДиапазона; рОбластьПараграфа.Шрифт = ПостроитьШрифт(ВыборШрифта(рДиапазон)); // а не рПараграф.Style.Font! рОбластьПараграфа.ГоризонтальноеПоложение = ПолучитьВыравнивание(рПараграф.Alignment); // или лучше рДиапазон.ParagraphFormat.Alignment? рОбластьПараграфа.ВертикальноеПоложение = ВертикальноеПоложение.Верх; // по умолчанию рОбластьПараграфа.РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Переносить; // по умолчанию #КонецОбласти стрк = стрк + 1; Иначе Если НЕ рИдётТаблица Тогда // выводим таблицу, а далее пропускаем все входящие в неё диапазоны, и идём до её конца ВывестиТаблицу(комВорд, комТаблица, т, стрк, рСантиметр); КонецЕсли; рИдётТаблица = Истина; Продолжить; // стрк уже "промотана" до нужной позиции пост-таблицы КонецЕсли; КонецЦикла; #КонецОбласти ЗакрытьДокумент(комДокумент); // без сохранения ЗакрытьВорд(комВорд); ИсправитьНедопустимыеСимволы(т); Возврат т; Исключение Ошибка = ОписаниеОшибки(); Причина = ИнформацияОбОшибке(); ЗакрытьДокумент(комДокумент); ЗакрытьВорд(комВорд); ВызватьИсключение("Ошибка конвертации в mxl", КатегорияОшибки.ОшибкаВнешнегоИсточникаДанных, "500", Ошибка, Причина); КонецПопытки; Возврат Неопределено; КонецФункции Функция ПостроитьШрифт(комШрифт) Возврат Новый Шрифт( комШрифт.Name, комШрифт.Size, комШрифт.Bold, комШрифт.Italic, комШрифт.Underline, комШрифт.StrikeThrough, комШрифт.Scaling ); КонецФункции Функция ВыборШрифта(рДиапазон) Результат = рДиапазон.Font; Если Результат.Size > 9999 Тогда Результат = рДиапазон.ListStyle.Font; КонецЕсли; Возврат Результат; КонецФункции Функция ПостроитьРамкуЯчейки(комРамка, чисОтступ) Если комРамка.Visible Тогда чисСтиль = комРамка.LineStyle; рТолщина = 1; Если чисСтиль = 1 Тогда рТипЛинии = ТипЛинииЯчейкиТабличногоДокумента.Сплошная; // если надо, толщину можно сделать подробнее по комРамка.LineWidth ИначеЕсли чисСтиль = 2 Тогда рТипЛинии = ТипЛинииЯчейкиТабличногоДокумента.Точечная; ИначеЕсли чисСтиль = 5 Тогда рТипЛинии = ТипЛинииЯчейкиТабличногоДокумента.РедкийПунктир; ИначеЕсли чисСтиль = 6 Тогда рТипЛинии = ТипЛинииЯчейкиТабличногоДокумента.ЧастыйПунктир; ИначеЕсли чисСтиль = 7 Тогда рТипЛинии = ТипЛинииЯчейкиТабличногоДокумента.Двойная; Иначе рТипЛинии = ТипЛинииЯчейкиТабличногоДокумента.БольшойПунктир; КонецЕсли; рОтступ = (чисОтступ > 0); // пока так Возврат Новый Линия(рТипЛинии, рТолщина, рОтступ); Иначе Возврат Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.НетЛинии); КонецЕсли; КонецФункции Функция ПолучитьВыравнивание(чисВыравнивание) // wdListLevelAlignCenter - 1 – По центру wdListLevelAlignLeft - 0 – По левому краю wdListLevelAlignRight - 2 – По правому краю Если чисВыравнивание = 1 Тогда Возврат ГоризонтальноеПоложение.Центр; ИначеЕсли чисВыравнивание = 2 Тогда Возврат ГоризонтальноеПоложение.Право; ИначеЕсли чисВыравнивание = 3 Тогда Возврат ГоризонтальноеПоложение.ПоШирине; Иначе Возврат ГоризонтальноеПоложение.Лево; КонецЕсли; КонецФункции Процедура ВывестиТаблицу(комВорд, комТаблица, табДокумент, текСтрока, рСантиметр = 6.25) // рСантиметр=6.25; рСимвол7 = Символ(7); квоСтрок = комТаблица.Rows.Count; квоКолонок = комТаблица.Columns.Count; Для стркДок = 1 По квоСтрок Цикл стлб = 1; Для стлбДок = 1 По квоКолонок Цикл Попытка комЯчейка = комТаблица.Cell(стркДок, стлбДок); Исключение Продолжить; КонецПопытки; квоЯчеекМхл = Окр(комВорд.PointsToCentimeters(комЯчейка.Width * 4), 0, РежимОкругления.Окр15как20); // 1 см. это 4 ячейки мхл рОбластьЯчейки = табДокумент.Область(текСтрока, стлб, текСтрока, стлб + квоЯчеекМхл - 1); рОбластьЯчейки.Объединить(); Если комЯчейка.FitText ИЛИ комЯчейка.WordWrap Тогда // пока так рОбластьЯчейки.РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Переносить; Иначе рОбластьЯчейки.РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Авто; КонецЕсли; рДиапазонЯчейки = комЯчейка.Range; // рТекстДиапазонаЯчейки = СокрЛП(рДиапазонЯчейки.Text); Если Прав(рТекстДиапазонаЯчейки, 1) = рСимвол7 Тогда рТекстДиапазонаЯчейки = Лев(рТекстДиапазонаЯчейки, СтрДлина(рТекстДиапазонаЯчейки) - 1); КонецЕсли; рОбластьЯчейки.Текст = рТекстДиапазонаЯчейки; // рОбластьЯчейки.Шрифт = ПостроитьШрифт(ВыборШрифта(рДиапазонЯчейки)); // на практике удобнее оставлять автовысоту, но иногда может понадобиться: // рОбластьЯчейки.АвтоВысотаСтроки=Ложь; //рОбластьЯчейки.ВысотаСтроки=рСантиметр*Окр(комВорд.PointsToCentimeters(комЯчейка.Height),0,РежимОкругления.Окр15как20); рОбластьЯчейки.ГоризонтальноеПоложение = ПолучитьВыравнивание(рДиапазонЯчейки.ParagraphFormat.Alignment); // отступ - в пунктах, при необходимости требуется пересчёт! // Если рОбластьЯчейки.ГоризонтальноеПоложение=ГоризонтальноеПоложение.Лево Тогда // рОбластьЯчейки.Отступ=комЯчейка.LeftPadding; // ИначеЕсли рОбластьЯчейки.ГоризонтальноеПоложение=ГоризонтальноеПоложение.Право Тогда // рОбластьЯчейки.Отступ=комЯчейка.RightPadding; //КонецЕсли; вертВыравнивание = комЯчейка.VerticalAlignment; Если вертВыравнивание = 1 Тогда рОбластьЯчейки.ВертикальноеПоложение = ВертикальноеПоложение.Центр; ИначеЕсли вертВыравнивание = 3 Тогда рОбластьЯчейки.ВертикальноеПоложение = ВертикальноеПоложение.Низ; Иначе рОбластьЯчейки.ВертикальноеПоложение = ВертикальноеПоложение.Верх; КонецЕсли; рОбластьЯчейки.ГраницаСверху = ПостроитьРамкуЯчейки(комЯчейка.Borders(-1), комЯчейка.Borders.DistanceFromTop); рОбластьЯчейки.ГраницаСлева = ПостроитьРамкуЯчейки(комЯчейка.Borders(-2), комЯчейка.Borders.DistanceFromLeft); рОбластьЯчейки.ГраницаСнизу = ПостроитьРамкуЯчейки(комЯчейка.Borders(-3), комЯчейка.Borders.DistanceFromBottom); рОбластьЯчейки.ГраницаСправа = ПостроитьРамкуЯчейки(комЯчейка.Borders(-4), комЯчейка.Borders.DistanceFromRight); стлб = стлб + квоЯчеекМхл; КонецЦикла; текСтрока = текСтрока + 1; КонецЦикла; КонецПроцедуры Процедура ЗакрытьДокумент(комДокумент) Если Неопределено = комДокумент Тогда Возврат; КонецЕсли; Попытка комДокумент.Close(Ложь); Исключение ; КонецПопытки; комДокумент = Неопределено; КонецПроцедуры Процедура ЗакрытьВорд(комВорд) Если Неопределено = комВорд Тогда Возврат; КонецЕсли; Попытка комВорд.Quit(0); Исключение ; КонецПопытки; комВорд = Неопределено; КонецПроцедуры //Строки = СтрРазделить("0,1,2,3,4,5,6,7,8,9", ","); //Числа = Мап("Результат = Число(Элемент) * _.Множитель", Строки, Новый Структура("Множитель", 2)); //Часть = Фильтр("Условие = Элемент > 4 * _.Множитель", Числа, Новый Структура("Множитель", 2)); //Сообщить(СтрСоединить(Часть, ",")); Функция ВыполнитьФрагмент(Знач Код, Вход, ИмяВход = "Вход", ИмяВыход = "Выход", Инициализировать = Ложь, _ = Неопределено) Выход = ?(Инициализировать, Вход, Неопределено); Если НЕ "Вход" = ИмяВход Тогда Код = СтрШаблон("%1=Вход;%2", ИмяВход, Код); КонецЕсли; Если НЕ "Выход" = ИмяВыход Тогда Код = СтрШаблон("%1;Выход=%2", Код, ИмяВыход); КонецЕсли; Выполнить(Код); Возврат Выход; КонецФункции Функция Мап(Код, Коллекция, _ = Неопределено) Результат = Новый Массив; Для Каждого Элемент Из Коллекция Цикл НовыйЭлемент = ВыполнитьФрагмент(Код, Элемент, "Элемент", "Результат", Истина, _); Результат.Добавить(НовыйЭлемент); КонецЦикла; Возврат Результат; КонецФункции Функция Фильтр(КодУсловия, Коллекция, _ = Неопределено) Результат = Новый Массив; Для Каждого Элемент Из Коллекция Цикл Условие = ВыполнитьФрагмент(КодУсловия, Элемент, "Элемент", "Условие", , _); Если Условие Тогда Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Функция ВыполнитьФрагмент_ДляСвертки(Знач Код, Элемент, Знач Результат, _ = Неопределено) Выполнить(Код); Возврат Результат; КонецФункции Функция Свернуть(Код, Коллекция, Знач Результат = Неопределено, _ = Неопределено) Для Каждого Элемент Из Коллекция Цикл Результат = ВыполнитьФрагмент_ДляСвертки(Код, Элемент, Результат, _); КонецЦикла; Возврат Результат; КонецФункции Функция ВзятьНеБольше(Коллекция, Знач Количество) Результат = Новый Массив; Для Каждого ТекСтр Из Коллекция Цикл Если 1 > Количество Тогда Прервать; КонецЕсли; Результат.Добавить(ТекСтр); Количество = Количество - 1; КонецЦикла; Возврат Результат; КонецФункции Функция Пропустить(Коллекция, Знач Количество) Результат = Новый Массив; Сч = 0; Для Каждого ТекСтр Из Коллекция Цикл Если 0 < Количество Тогда Количество = Количество - 1; Продолжить; КонецЕсли; Результат.Добавить(ТекСтр); КонецЦикла; Возврат Результат; КонецФункции Функция АлфавитСистемСчисления(Нотация=36) Алфавит = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; ДлинаАлфавита = СтрДлина(Алфавит); Результат = ""; Если ДлинаАлфавита = Нотация Тогда Результат = Алфавит; ИначеЕсли ДлинаАлфавита > Нотация Тогда Результат = Лев(Алфавит, Нотация); Иначе ВызватьИсключение "Алфавит слишком мал"; КонецЕсли; Возврат Результат; КонецФункции Функция ЧислоВДругуюСистему(Знач Значение = 0, Нотация = 36) Если Нотация <= 0 Тогда Возврат ""; КонецЕсли; Значение = Цел(Число(Значение)); Если Значение <= 0 Тогда Возврат "0"; КонецЕсли; Алфавит = АлфавитСистемСчисления(Нотация); Результат = ""; Пока Значение > 0 Цикл Результат = Сред(Алфавит, Значение % Нотация + 1, 1) + Результат; Значение = Цел(Значение / Нотация); КонецЦикла; Возврат Результат; КонецФункции Функция ЧислоИзДругойСистемы(Знач Значение = "0", Нотация = 36) Если Нотация <= 0 Тогда Возврат 0; КонецЕсли; Значение = СокрЛП(Значение); Если Значение = "0" Тогда Возврат 0; КонецЕсли; Алфавит = АлфавитСистемСчисления(Нотация); Результат = 0; Длина = СтрДлина(Значение); Для Позиция = 1 По Длина Цикл Множитель = Pow(Нотация, Длина - Позиция); ТекСимвол = Сред(Значение, Позиция, 1); ИндексСимвола = СтрНайти(Алфавит, ТекСимвол) - 1; Результат = Результат + ИндексСимвола * Множитель; КонецЦикла; Возврат Окр(Результат); КонецФункции Функция Ох(Знач Стр) Возврат ЧислоИзДругойСистемы(Стр, 16); КонецФункции Функция Hex(Знач Числ) Возврат ЧислоВДругуюСистему(Числ, 16); КонецФункции Процедура ЗаменитьТекстВТД(ТД, Текст, Замена) Область = ТД.НайтиТекст(Текст); Пока НЕ Неопределено = Область Цикл Область.Текст = СтрЗаменить(Область.Текст, Текст, Замена); Область = ТД.НайтиТекст(Текст, Область); КонецЦикла; КонецПроцедуры Функция МассивПоДиапазонуЧисел(Число_С, Число_По) Результат = Новый Массив; Для ТекЧисло = Число_С По Число_По Цикл Результат.Добавить(ТекЧисло); КонецЦикла; Возврат Результат; КонецФункции Функция СформироватьДиапазон(МассивОписанияДиапазона) Результат = Неопределено; Если 1 = МассивОписанияДиапазона.Количество() Тогда Результат = Новый Массив; Результат.Добавить(МассивОписанияДиапазона[0]); ИначеЕсли 2 = МассивОписанияДиапазона.Количество() Тогда Результат = МассивПоДиапазонуЧисел(МассивОписанияДиапазона[0], МассивОписанияДиапазона[1]); Иначе ВызватьИсключение СтрШаблон("Ошибка в описании диапазона: %1 элементов", МассивОписанияДиапазона.Количество()); КонецЕсли; Возврат Результат; КонецФункции Процедура ИсправитьНедопустимыеСимволы(ТабДок) // список символов из: // https://ru.wikipedia.org/wiki/%D0%A3%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D1%8F%D1%8E%D1%89%D0%B8%D0%B5_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D1%8B ИнтервалыКодов = "0-1F,7F,80-9F,034F,2008,200B-200F,2028-202E,2060-2061,2063,2066-206F," + "FE00-FE0F,FEFF,FFF9-FFFD,E0100-E01EF"; ИнтервалыКодов = СтрРазделить(ИнтервалыКодов, ","); ИнтервалыКодов = Мап("Результат = СтрРазделить(Элемент, ""-"")", ИнтервалыКодов); ИнтервалыКодов = Мап("Результат = Мап(""Результат = Ох(Элемент)"" ,Элемент)", ИнтервалыКодов); ИнтервалыКодов = Мап("Результат = СформироватьДиапазон(Элемент)", ИнтервалыКодов); УпрСимволы = Свернуть("ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, Элемент)", ИнтервалыКодов, Новый Массив); УпрСимволы = Мап("Результат = Символ(Элемент)", УпрСимволы); УпрСимволы = ОбщегоНазначенияКлиентСервер.СвернутьМассив(УпрСимволы); Исключения = Мап("Результат = Символы[Элемент]", СтрРазделить("ПС,ВК", ",")); УпрСимволы = Фильтр("Условие = Неопределено = _.Найти(Элемент)", УпрСимволы, Исключения); ЗаменитьТекстВТД(ТабДок, Символы.ВТаб, Символы.ПС); Для Каждого ТекСимвол_Число Из УпрСимволы Цикл ЗаменитьТекстВТД(ТабДок, ТекСимвол_Число, ""); КонецЦикла; КонецПроцедуры