Габец А. П. - 1С Предприятие 8.0. Простые примеры разработки

Книга представляет собой справочное пособие, иллюстрирующее простые примеры разработки алгоритмов на платформе «1С:Предприятие 8.0».
Издание будет полезно начинающим разработчикам, администраторам, у которых на предприятии внедряется система, и продвинутым пользователям, которые хотят самостоятельно дорабатывать прикладные решения.
Книга содержит большое количество практических примеров, сгруппированных по тематике использования. Кроме этого книга содержит подробный указатель на используемые в примерах свойства, методы и события встроенного языка.
Данная книга дополняет, но не заменяет штатную документацию к программному продукту, входящую в комплект поставки, и позволяет более эффективно использовать возможности программы.
Введение
Идея написать эту книгу возникла у нас не случайно. Платформа системы «1С: Предприятие 8.0» специально ориентирована на то, что ее будут использовать не только как средство разработки, но и как инструмент быстрой доработки «на месте». В таких случаях специалисту важно в сжатые сроки решить конкретную задачу без долгого изучения всех возможностей системы.
Как преподаватели учебного центра - мы, разумеется, только за то, чтобы специалист был изначально методологически и всесторонне «подкован». Но как практикующие разработчики, кроме всего прочего, зачастую и сами с большей радостью используем описанные примеры решения тех или иных задач, нежели пытаемся воссоздать их по памяти или по методическим материалам.
Собственно говоря, именно с целью помочь в подобных ситуациях, и была написана эта книга. Основой ее создания послужил опыт преподавания «программистских курсов» по системе, работа на конкретных внедрениях и активное общение в форумах, посвященных данному кругу проблем. Фактически книга составлена в результате анализа того, какие задачи приходится решать чаще всего как начинающим, так и продвинутым разработчикам.
При подборе примеров мы исходили из того, что спектр навыков и знаний специалистов, которые будут работать с данным изданием, может быть очень широк. Поэтому пусть Вас не смущают некоторые особо «бородатые» советы или, наоборот, - отсутствие подробного описания тех или иных технологий. А для тех, кто практически не знаком с системой «1С:Предприятие 8.0», материал самых простых примеров, объясняющих азы использования объектов и механизмов системы, помечен специальным значком ф.
Кроме этого, поскольку работа с настоящим изданием не требует досконального чтения всего материала, по тексту намеренно вставлены повторы некоторых приемов или предостережений в тех случаях, когда это имеет смысл.
Также следует заметить, что мы стремились сделать именно сборник простых примеров, поэтому некоторые материалы вошли в издание в «разрезанном» виде. То есть вместо сложных и громоздких «сквозных» примеров, мы старались представить отдельные части, «кирпичики», из которых впоследствии можно собрать желаемое.
Стиль изложения соответствует цели издания, поэтому материал предоставляется в форме вопросов и ответов, как, например, в следующем разделе:
Как работать с изданием?
Решение данного вопроса - многовариантно.
Можно читать классическим способом. От начала до конца, помечая или закладывая понравившиеся места. Впоследствии, при возникновении конкретных вопросов, зрительная память или закладки помогут найти нужное решение.
Можно читать выборочно. Любимая поговорка крутых программистов: «Мануал открывать надо уже в последний момент». То есть, проблема возникла - нашли раздел и попытались найти решение, или идею решения по аналогии. Но поговорку, на самом деле, мы совсем не одобряем!
Можно вообще не читать. Не читать комментарии. А рассматривать издание как сборник «шпаргалок» кода, решающего те или иные вопросы.
Остальные варианты использования издания или не очень нравятся авторам, или достаточно опасны. Например, не надо рассматривать эту книжку как замену полноценного обучения или работы с методическими материалами.
Примитивные типы, системные функции
Как явно указать нужную дату?
Для указания нужной даты можно пользоваться:
• литералом вида ТГГГММДДччммсс' встроенного языка;
• встроенной функцией преобразования значений Дата();
• литералом типа Дата языка запросов.
В таблице ниже приводится ряд возможностей явного указания даты при помощи встроенного языка:
|
Выражение |
Значение результата (тип) |
|
'20050308' |
08.03.2005 0:00:00 (Дата) |
|
Дата(2005, 1,1) |
01.01.2005 0:00:00 (Дата) |
|
Дата(1, 1, 1) |
01.01.0001 0:00:00 (Дата) |
|
Дата(2005, 1, 1, 10, 29, 50) |
01.01.2005 10:29:50 (Дата) |
В случае же, если в тексте запроса необходимо жестко указать некую дату - используется литерал ДАТАВРЕМЯ(). Например, поле со значением '01.01.2005 0:00:00' можно получить так:
ДАТАВРЕМЯ(2(Ю5,01.01)
Как проверить дату на пустое значение?
Значение типа Дата не бывает «пустым». Если в явном виде значение переменной типа Дата не задано, она будет иметь значение по умолчанию: начало первого дня первого месяца первого года (00 часов 00 минут 00 секунд). Поэтому проверку проще сделать так:
Если ДатаПроверяемая = Дата(I, I, 1)Тогда Сообщить("Пустая дата!");
КонецЕсли;
Как сравнить две даты (дни)?
Точность данных типа Дата - до секунды. А сравнивать нужно именно дни.
Тогда проще предварительно для сравниваемых дат воспользоваться функцией, которая возвращает, например, дату начала дня. А потом уже сравнивать полученные значения.
Если НачалоДня(Дата 1) = НачалоДня(Дата2) Тогда СообщитьСДни совпадают!");
КонецЕсли;
Как прибавить к дате день, месяц?
Так как тип Дата содержит дату и время с точностью до секунды, то для того чтобы к некоторой дате прибавить один день, нужно увеличить ее значение на количество секунд, содержащихся в одном дне:
СледующийДень = ТекущаяДатаО + 60 * 60 * 24:
Для увеличения или уменьшения даты на некоторое количество месяцев, можно использовать:
• функции работы со значением типа Дата во встроенном языке;
• функции работы со значением типа Дата в запросах.
В таблице ниже приводится ряд возможностей использования функций встроенного языка:
|
Выражение |
Значение результата (тип) |
|
ДобавитьМесяц(Дата(2005, 1, 31), 1) |
28.02.2005 0:00:00 (Дата) |
|
ДобавитьМесяц(Дата(2005, 2, 28), -1) |
28.01.2005 0:00:00 (Дата) |
|
КонецМесяца(ДобавитьМесяц(Дата(2005, 2, 28), -1)) |
31.01.2005 23:59:59 (Дата) |
А вот пример функции, добавляющей количество дней к исходной дате при помощи запроса:
Функция ПолучитьДень(ИсходнаяДата, Количсс і воПрибавлясмыхДнсй)
Запрос = Новый Запрос("
ІВЫБРАТЬ
I ДОБАВИТЬКДАТЕ(&ИсходнаяДата. ДЕНЬ, &Количсство) как Дата");
Запрос.УстановитьПараметрС'ИсходнаяДата", Исходная Дата); Запрос.Установиі(.Параметре"Количество", КоличествоПрибавляемыхДней):
Возврат Запрос.Выполннть().Выгрузить()[0].Дата;
КонецФункции
В тексте запроса используем функцию ДОБАВИТЬКДАТЕ(). В качестве параметров ей необходимо передать исходную дату, тип добавляемых периодов (в нашем случае жестко прописали «День») и количество добавляемых периодов.
Первый и последний параметры передали запросу, считав их из параметров (заголовка) нашей функции.
Далее запрос выполняется, и из него получаем значение выходного поля по первой (и единственной) строке.
Результаты выполнения вышеприведенной функции будут такими:
ПолучитьДень('20052802', 10) = 10.03.2005 0:00:00
ПолучтъДень(
,20042802', 10) - 09.03.2004 0:00:00, поскольку 2004 год был високосным!
Как можно проверить тип значения переменной на равенство нужному?
ИмяНужногоТипа = "ДокументСсылка.РеализацияТоваров";
Если ТипЗнч(ОбрабатываемыйДокумент) = Тии(ИмяНужногоТипа) Тогда //Строки кода, выполняемые при истинности условия.
КонецЕсли;
ТипЗнч() - функция языка, возвращающая по значению его тип. Тип () - функция языка, возвращающая значение типа Тип по
строковому имени типа.
Как очистить реквизит формы, имеющий ссылочныйтип?
К примеру, реквизит (имя «Товар») имеет тип СправочникСсылка.Номенклатура. Для очистки значения в связанном с ним элементе управления на форме, необходимо выполнить строку кода:
Товар = Справочники. Номенклатура. ПустаяСсылкаО;
То есть необходимо установить значение по умолчанию. А им, в данном случае, будет пустая ссылка на элемент справочника «Номенклатура».
Как очистить значение, имеющее тип «Хранилище значения»?
Очистить значение, записанное в реквизит или ресурс (имя «РеквизитХранилище») можно следующим образом:
РеквизитХранилише = Неопределено:
Как проверить тип значения, помещенного в реквизит имеющий тип «Хранилище значения»?
По причинам не связанным с возможностями системы 1С:Предприятие 8.0, в реквизит «Фотография» (тип ХранилищеЗначения) справочника «Сотрудники» помещалась либо Строка (преобразованная к типу ХранилищеЗначения), либо Картинка (преобразованная к типу ХранилищеЗначения). Как проверить, что было записано?
Проверку можно осуществить, используя следующие строки кода:
Значение = Фотография.ПолучитьО:
Если Значение о Неопрсделено Тогда Если ТипЗнч(Значение) = ТипГСтрока") Тогда // Обработать строку.
ИначеЕсли ТипЗнч(Значение) = ТнпСКартинка”) Тоі да
// Обработать картинку.
Сообщить(" Картинка");
КонецЕсли;
КонецЕели;
Следует отметить, что в реквизит имеющий тип ХранилищеЗначения можно поместить только значение, имеющее тип ХранилищеЗначения. Работа со значением, помещенным в хранилище значения, может начаться только после его получения (метод Получить()). После получения значение «восстанавливает свой прежний тип». Если полученное значение равно Неопределено, то это означает, что никакое значение в реквизит не записывалось.
Как сжать данные, помещаемые в хранилище значения?
Допустим, в реквизит «СопроводительнаяИнформация» (тип значения - Хранилище значения) помещается значение переменной «ПомещаемоеЗначение». Нужно обеспечить максимальное сжатие данных закладываемого значения.

Вторым параметром конструктора хранилища значения передается объект СжатиеДанных. Он тоже получен соответствующим конструктором, с указанием максимального уровня сжатия.
Как предоставить пользователю возможность выбора значения составного типа?
МассивТипов = Новый Массив;
МассивТ ипов.Добавить(Тип("С'правочникСсыакаФи'іЛица")) // Добавить другие типы.
ОписамисВозможныхТипов = Новый ОписаниеТипов(МассивТипов); ПолученноеЗначение = Неопредслено; ВвестиЗначеииеШолученноеЗначение,
"Выберите значение:",
ОпнсаниеВозможныхТипов);
Для реализации этой задачи необходимо воспользоваться конструктором объекта ОписаниеТипов. А для него необходимо передавать в качестве параметра массив разрешенных для вводимого значения типов значения.
Когда конструктором «ОписаниеВозможныхТипов» собрано -применяем функцию для вызова диалога ввода данных ВвестиЗначениеО.
Первым параметром функции необходимо указать доступную в данном модуле переменную для принятия введенного значения. Вторым - заголовок открываемого окна. Третьим - объект ОписаниеТипов.
После ввода значения пользователем можно считать значение с переменной, переданной первым параметром.
Как применить округление при работе с вычисляемыми числовыми полями в запросе?
Например, составляется запрос для оценок средней цены продажи по данным регистра «Продажи». Для получения данных с точностью до двух знаков после запятой текст запроса может выглядеть следующим образом:
|
ВЫБРАТЬ |
|
ПродажиОбороты. Номенклатура.
ВЫРАЗИТЫ |
|
|
П родажиОбороты. Стой мостьОборотЯ 1 родажиОбороты. Кол и чсствоОборот |
|
|
КАК ЧИСЛО(15, 2)) |
|
КАК СредняяЦенаПродажи |
|
|
ИЗ |
|
|
РегистрНакоплення.Продажи.Обороты(&ДатаНач. &ДатаКон) |
|
КАК ПродажиОбороты |
|
Источником для запроса является виртуальная таблица «РегистрНакопления.Продажи.Обороты», построенная по данным регистра в интервале между «ДатаНач» и «ДатаКон».
В качестве выходных полей берем «Номенклатура» и результат деления значения полей источника «СтоимостьОборот» и «КоличествоОборот». Причем оператором ВЫРАЗИТЬ() тип последнего поля приводится к примитивному типу ЧИСЛО с определенным форматом (длинна 15, точность 2).
Как вывести многострочное предупреждение?
Переменные «Остаток» и «Зарезервировано» содержат значения, которые необходимо вывести в виде предупреждения. Кроме того, нужно еще вывести свободный остаток, вычисляемый по формуле:
СвободныйОстаток = Остаток - Зарезервировано.
Все это может быть выполнено следующим образом:
Предупреждениер'На складе: ” + Остаток + Снмволы.ПС +
"В речерве : " + Зарезервировано + Символы.ПС + "Свободный остаток:" + (Остаток - Зарезервировано), 20,
"Состояние остатков''):
Процедура глобального контекста Предупреждение() выводит на экран модальное окно предупреждения. Текст предупреждения передается первым параметром, вторым - таймаут, содержащий указание количества секунд, через которое окно самостоятельно закроется (если раньше его не закроет пользователь), третьим - указывается заголовок окна.
Многострочность предупреждения в нашем примере осуществляется за счет добавления значения ПС (перевод строки) системного набора значений СИМВОЛЫ в текст предупреждения.
Обратите внимание на вычисление свободного остатка в скобках -для обеспечения корректности выполнения арифметических действий и преобразования данных к типу Строка.
Кроме того, хотелось бы предупредить об опасности попыток применения процедуры Предупреждение() в ходе проведения документов. Проведение документов выполняется в транзакции, поэтому использование каких либо интерфейсных решений, останавливающих работу системы, является совершенно неприемлемым. В подобных случаях лучше информировать пользователей посредством Сообщить().
Какпри выполнении обработки сообщить пользователю текущее время?
ТекущееВрсмя = Формат(ТекушаяДата(), "ДЛФ=В"); Сообщить(ТекущссВремя);
Метод ТекущаяДата() возвращает системную дату. Тип значения -Дата. В его значение входит и дата и время.
Для получения представления только времени можно применяем функцию Формат().
Как вывести число прописью по-русски, но без дробной части?
Для этого используется функция ЧислоПрописью(). У нее могут быть указаны в качестве параметров:
• преобразуемое число;
• форматная строка;
• параметры предмета исчисления (вид этой форматной строки определяется значением кода локализации).
Все возможные варианты локализаций описаны в файле Locllnfo.txt, входящем в комплект поставки программы.
Для решения нашей задачи можно использовать следующий текст:
ФорматнаяСтрока = "JI=ru_RU”; ПарамстрыПредметаИсчисления = О";
С ообщить(ЧислоПрописью( ВыводимоеЧисло, ФорматнаяСтрока, ПараметрыПредмстаИсчисления)):
В форматной строке указываем код локализации - Русский(Россия). В параметрах предмета исчисления показываем, что дробная часть не должна содержать ни одного разряда.
Для ВыводимоеЧисло = 234,4 результат будет: «Двести тридцать четыре».
Как вывести число прописью по-русски, с указанием сотых в дробной части?
|
ПарамстрыПредметаИсчисления = |
|
|
"целая, целых, целых. |
к, сотая, сотой, сотых, ж. 2": |
|
ФорматнаяСтрока = "JI=ru_RU; ДП=Истина"; |
|
|
Сообщить! ЧислоПрописью(ВыводимоеЧисло. |
|
|
ФорматнаяСтрока, |
|
|
ПарамстрыПредметаИсчисления)); |
В параметрах предмета исчисления указываем возможные спряжения и склонения слов «целая» и «сотая», а так же количество разрядов дробной части, которые будут выводиться прописью.
В форматной строке указываются код языка локализации и необходимость вывода дробной части прописью.
Для ВыводимоеЧисло - 123,45 результат будет: «Сто двадцать три целых сорок пять сотых».
Как вывести прописью число килограммов с указанием дробной части в граммах?
ПараметрыПредметаИсчисления - "килограмм, килограмма, килограммов, м,
|грамм, грамма, граммов, м, 3"; ФорматнаяСтрока = ”JI=ni_RU; ДП=Истина";
Сообщи гь(ЧислоПрописью(ВыводимоеЧисло,
ФорматнаяСтрока. ПараметрыПредметаИсчисления));
В отличие от вышеприведенного примера здесь предметами исчисления являются килограммы и граммы, а количество разрядов дробной части - три.
Для ВыводимоеЧисло = 12,345 результат будет: «Двенадцать
килограммов триста сорок пять граммов»
Как долларовую сумму вывести прописью по-английски?
ФорматнаяСтрока = "JI=en_US";
ПараметрыПредметаИсчисления ="do!lar, dollars, cent, cents, 2"
Сообщить(ЧислоПрописыо(Сумма,
ФорматнаяСтрока,
ПараметрыПредметаИсчисления)):
Для ВыводимоеЧисло = 1 232,45 результат будет: «One thousand two hundreds thirty two dollars 45 cents»
Как загрузитьвнешнюю компоненту?
Загрузим компоненту, позволяющую работать со сканером штрихкодов:
Попытка
ЗагручитьВнешнююКомпонентуІ’’scanopos.dll") Исключение
СообщитьГОшибка загрузки внешней компоненты!");

В случае ошибки загрузки компоненты или создания объекта возникает исключительная ситуация, которую рекомендуется отрабатывать с помощью конструкции Попытка.
Как выполнить команду операционной системы?
К примеру, требуется удалить все файлы из указанного каталога.
Для реализации данной возможности достаточно выполнить следующую строку кода:
|
КомаіідаСистсмы("Де1 *.* /q", "c:\temp"): |
|
|
|
|
Для просмотра доступных команд можно в командной строке системы выполнить команду «help».
Вызвать командную строку, можно выполнив строку кода:
КомандаСистемы("сіжГ):
Кроме этого, для запуска внешнего приложения (или открытия файла с использованием ассоциированного с ним приложения) может быть использован метод глобального контекста ЗапуститьПриложение(). В этом случае запуск приложения будет осуществляться непосредственно, минуя командный интерпретатор. Например:
ЗапуститьПриложение("ШаблонДоговора.(1ос"):
Как реализовать код процедуры в зависимости от режима выполнения (на клиенте, на сервере, во внешнем соединении) ?
Если алгоритм должен выполняться по-разному в зависимости от места выполнения процедуры, то можно воспользоваться инструкциями препроцессора:
#Если ВнешнееСоедннение Тогда
// Фрагмент кода, который должен выполняться в сессии внешнего соединения. #КонецЕсли #Еслн Клиент Тогда
// Фрагмент кода, который должен выполняться на сервере.
#КонецЕсли #Если Сервер Тогда
// Фрагмент кода, который должен выполняться на клиентском месте.
#КонецЕсли
Как при групповой обработке объектов реализовать стратегию «либо все, либо ничего»?
Требуется загрузить либо все данные по справочнику «Единицы измерения», либо, в случае возникновения ошибки, нужно чтобы ни один элемент не был записан.
Для реализации стратегии «либо все, либо ничего» можно использовать следующий фрагмент кода:
|
НачатьТранзакцию(); |
|
|
// В переменной "ВыборкаДанных" содержатся данные дл Пока ВыборкаДанных.СледующийО Цикл |
записи в справочник. |
|
Элемсн іОбъект - Справочники.ЕдиницыМзмерения.СоздатьЭлсментО; |
ЭлементОбьект.Код = Выборка.Код:
ЭлементОбъект.Наименование = Выборка.Наименовани |
|
|
// Остальные реквизиты |
|
ЭлемснтОбъект.ЗаписатьО;
Конец Цикл а; |
|
|
Зафиксировать! рантакцнюО; |
|
Если необходимо но мере накопления каких-либо признаков «искусственно» отменить действия, совершаемые в транзакции, можно использовать метод системы:
ОтмснитьТрантакциюО;
Как посчитать сумму по формуле сложного процента?
Пусть первоначальная сумма долга равна Р, тогда через один год
/>(1 + і)
сумма долга с присоединенными процентами составит
? 7, через п
Р(і + і)
п.
лет -
? 7
Таким образом, получаем формулу наращения для сложных процентов:
S = p{l + i)
n,
где S - наращенная сумма, і - годовая ставка сложных процентов, п - срок ссуды,
Для вычисления можно использовать функции работы со значениями типа «число»:
Функция СложныйІ1роцент(Креднт, Ставка. Срок = 1) Возврат Креднт*Ро\?( I + Ставка/100, Срок); КонецФункции
Возведение в степень реализуется функцией Pow(). Первым параметром передается основание степени, вторым - показатель степени.
Замечание: кроме работы со степенями математический аппарат системы позволяет работать с корнями, логарифмами и тригонометрическими функциями.
Универсальные коллекции
Массив
(!) В каких ситуациях обычно используются массивы?
Массив является универсальной коллекцией, то есть объектом, предназначенным для работы с временными наборами данных в течение сеанса работы пользователя.
Необходимость в его использовании возникает, когда требуется работать с временным набором данных. Чаще всего это промежуточные операции обработки информации: подготовка отборов, реализация поиска, подготовка группирования, передача параметров и проч.
Массивы могут создаваться оператором Новый или получаться в результате применения методов некоторых объектов.
(D Как создать массив?
Создание массивов чаще всего происходит посредством оператора
Новый:
СозданныйМассив = Новый Массив ();
где «СозданныйМассив» - имя переменной, которая будет содержать созданный объект типа Массив. После создания к массиву можно добавлять элементы (произвольное количество).
Если же мы хотим создать массив с заранее определенной размерностью, это можно сделать так:
СозданныйМассив = Новый Массив (10):
В результате в переменной «СозданныйМассив» будет создан массив с десятью значениями. Для такого массива можно потом сразу обращаться к любому из десяти значений (начиная с нулевого по девятое) для записи или для чтения. А при необходимости к такому массиву можно так же еще добавлять новые элементы. Первый же добавленный элемент получит индекс «10».
Как создать многомерный массив?
Массив является линейной динамической коллекцией с произвольным типом значений. Поэтому значениями массива могут выступать другие массивы.
То есть создание массива массивов и решает задачу создания многомерного массива.
Это можно делать при использовании конструктора массива:
ДвумерныйМассив = Новый Массив (2, 8):
или в процессе добавления очередных элементов к массиву:
ДвумерныйМассив = Новый Массив;
МассивВторогоПорядка = Новый Массив (8):
ДвумерныйМассив.Добавить(МассивВторогоПорядка): Дву мерныйМассив. Добавить! МассивВторогоПорядка):
И в том и в другом случае мы решим задачу создания двумерного массива размерностью 2x8.
Чтение и запись значений такого массива можно производить посредством директивного указания индексов:
Значение = ДвумерныйМассив[21[5);
или при помощи метода Получить():
Значение = ДвумерныйМассив.Получить(2).Получить(5);
Хотелось бы еще раз отметить, что создание массива определенной размерности конструктором ограничивает только количество возможных к заполнению значений массива, но не препятствует добавлению новых значений (в качестве которых могут выступать массивы произвольной размерности).
Как добавить элементы в массив?
Допустим, массив, к которому нужно добавить значение из переменной «НовоеЗначение», называется «НашМассив».
Если нужно просто добавить очередной элемент (с индексом на единицу больше самого старшего) - действуем следующим образом:
ІІашМассив.Добавить(НовоеЗначение)
Если нужно, чтобы новые значения добавлялись с определенным индексом, то можно использовать метод Вставить():
Массив = Новый Массив;
Массив.Вставить(5, "ООО ""Лабан......);_ •
Как определить размер массива?
Чтобы определить количество элементов массива «НашМассив» можно сделать так:
Рачмер = НашМассив. Количествен:
Однако имейте в виду, поскольку индексация элементов массива начинается с нуля - значение переменной «Размер» будет на единицу больше значения самого старшего индекса.
Как обратиться к элементу массива?
При обращении как для записи, так и для чтения элементов массива лучше пользоваться оператором [ ], указывая индекс элемента. Помните, что индексация начинается с нуля.
Пусть в переменную «ПервоеЗначение» нужно считать значение самого первого элемента массива, а в элемент массива с индексом «9» записать значение из переменной «ДесятоеЗначение»:
ПервосЗначение = НашМассив[0]; НашМассив|9| = ДесятоеЗначенис:
Аналогичных результатов можно добиться при помощи методов
Получить() и Установить():
ПервосЗначение = НашМасспв.Получнть(О); НашМасснв.Установить(9, ДесягоеЗначение):
Замечание: в любом случае, чтобы иметь возможность обратиться к элементу массива, он должен уже существовать. Иначе получим ошибку с сообщением о том, что индекс находится за границами массива.
Как перебрать элементы массива?
Если перебор элементов массива нужен для чтения данных из массива - проще всего организовывать посредством цикла перебора коллекции.
Например, чтобы вывести сообщения о каждом числе, найденном в массиве «МассивЭлементов», достаточно сделать следующее:

Обратите внимание, «ЭлементМассива» - это произвольное имя переменной, принимающей в себя очередное значение элемента коллекции при выполнении цикла.
Если же при переборе элементов массива нужно их редактировать, то для этого нужно работать еще и с индексами элементов. Лучше тогда использовать так называемый «цикл-счетчик».
Например, чтобы обнулить все числовые элементы массива, достаточно сделать следующее:
Для Сч = 0 по МассивЭлементов.ВГраннцаО Цикл
Если ТипЗнч(МассивЭлементов[Сч|) = ТипСЧисло") Тогда МассивЭлементов[Сч) = 0;
КонецЕсли;
КоиецЦикла;
«Сч» - это переменная, принимающее очередное значение счетчика на каждом выполнении цикла. Именно из нее и будем считывать значение индекса очередного элемента массива.
Значение самого большого индекса массива определяется посредством метода ВГраница().
Как удалить элемент массива?
Удаление отдельных элементов массива происходит с обязательным указанием индекса удаляемого элемента. Так, например, будет удален первый элемент массива:
МассивЭлементов.Удалить(О);
Естественно, если указанный индекс будет выходить за границы массива - получим сообщение об ошибке.
Кроме того, необходимо учитывать, что удаление элемента «из середины» массива приведет к уменьшению на единицу индексов элементов, стоявших «после» удаленного. Массив как бы «сомкнет ряды».
Поэтому, например, один из наиболее простых вариантов удаления всех числовых элементов массива может выглядеть так:

Сначала определяем самый старший индекс элементов массива. Цикл проверок и удалений чисел будет выполняться, пока очередное значение индекса не окажется меньше нуля.
В цикле определяем тип значения элемента с текущим индексом. Если это число - удаляем данный элемент. Кроме того, в любом случае уменьшаем на единицу значение переменной «Индекс».
В результате, поскольку перебор элементов массива проводится с конца, эффект «смыкания рядов» будет производиться только для уже проверенных элементов.
® Как удалить все элементы массива?
Если требуется полное удаление элементов из массива, операция выполняется гораздо проще:
Массив.ОчиститьО;
Как удалить повторяющиеся элементы массива?
Поскольку объект «массив» является одной из самых простых универсальных коллекций, методами поиска по значению он не обладает. Поэтому для того, чтобы удалить повторяющиеся элементы, следует перебрать все элементы массива и проверить их значения.

Для выполнения поставленной задачи организуется два цикла: в первом цикле осуществляется перебор элементов массива и для каждого выбранного элемента осуществляется вложенный цикл сравнения текущего элемента с последующими элементами массива. В случае совпадения значений последующий элемент массива удаляется.
Когда для очередного элемента с индексом «ТекущийИндекс» завершился вложенный цикл проверки с последующими - увеличиваем значение «ТекущийИндекс» на единицу с тем, чтобы следующий по индексу элемент попал в положение проверяемого.
Как скопировать массив?

Для получения копии массива в другом объекте (массиве) необходимо создать новый массив (массив-копию) конструктором. Далее в цикле перебора элементов исходного массива добавлять эти элементы в массив-копию.
Как проверить, что два массива идентичны?
Это можно выполнить при помощи следующей функции. В качестве параметров ей передаются сами проверяемые массивы «ПервыйМассив» и «ВторойМассив».
Функция ПроверитьИдснтичностьМассивовН ІервыйМассив. ВторойМассив)
НаибольшийИндекс = ПервыйМассив.ВГраницаО;
Если НаибольшийИндекс о ВторойМассив.ВГраница () Тогда Возврат Ложь;
КонецЕсли:
Для Счетчик = 0 По НаибольшийИндекс Цикл
Если ПервыйМассив[Счетчнк] о ВторойМассив[Счегчик] Тогда Возврат Ложь;
КонецЕсли;
КонсцЦикла;
Возврат Истина;
КонсцФункции
Сначала проверяем совпадение наибольших индексов в массивах, если совпадения нет - массивы уже не идентичны. Значит функция возвращает значение ЛОЖЬ
Далее необходимо произвести проверку идентичности элементов массивов с одинаковыми индексами. Поскольку индексация элементов массива начинается с нулевого значения — выполняем цикл-счетчик от нуля до значения наибольшего индекса массива.
Внутри цикла при выполнении неравенства очередных элементов функция возвращает значение Ложь.
Если цикл пройден до конца - значения всех элементов с одинаковыми индексами совпали.
Значит функция может вернуть значение Истина.
В массив выгружены данные, содержащие наименования контрагентов. Как их отсортировать?
Список значений позволяет выполнять сортировки по представлению или по значению и, кроме того, обладает возможностями загрузки данных из массива и выгрузки в массив. Поэтому один из вариантов решения данной задачи может быть таким:
СписокЗначений = Новый СписокЗначений;
СннеокЗначений.ЗагруіитьЗначения(МассивНаименований);
СписокЗначений.СортироватьПоЗначениюО;
МассивНаименовашій = СписокЗначений. ВыгручитьЗначенияО:
Создаем список значений.
Загружаем значения из массива «МассивНаименований».
Сортируем список значений по значениям. Поскольку параметр не указали, направление сортировки будет - по возрастанию. Если нужно по убыванию - в качестве параметра надо передать соответствующее значение системного перечисления НаправлениеСорТИрОВКИ:
СписокЗначений. СортироватьГІоЗначениюШаправ.іенпеСортировки. Убыв!
После выполнения сортировки значений в массив.
выгружаем значения
из
списка
Есть массив, в который выгружены значения типа СправочникСсылка.Номенклатура. Как удалить все пустые значения массива?
Процедура УдалитьПустыеЭлементы(МассивНоменклатуры) Счетчик = О:
КоличествоЭлемснтов = МассивНомснклатуры.Количество!);
Пока Счетчик < КоличествоЭлемснтов Цикл
Если МассивНомснклатуры [Счетчик].ПустаяО Тогда МассивНоменклатуры.Удалить(Счетчик); КоличествоЭлемснтов = КоличествоЭлементов - 1;
Иначе
Счетчик = Счетчик + 1;
КонецЕсли:
КонецЦикла;
КонецПроцедуры
Получаем в виде параметра процедуры массив номенклатурных позиций.
Устанавливаем нулевое значение счетчика - переменной «Счетчик».
Организуем цикл, который будет выполняться, пока значение переменной «Счетчик» меньше количества элементов массива. Поскольку индексы элементов массива начинаются с нулевого значения, то наш цикл прервется в момент, когда значения индекса («Счетчик») и количества элементов совпадут.
Внутри цикла проверяется условие, является ли ссылка, содержащаяся в очередном элементе массива - пустой. Если это так -текущий элемент массива удаляется. В результате у следующих за ним элементов автоматически на единицу уменьшаться индексы. Кроме того, необходимо уменьшить на единицу значение переменной, отслеживающей количество элементов в массиве.
Если же ссылка не пустая - увеличивается на единицу значение «Счетчик» с тем, чтобы на следующем ходе цикла работать уже со следующим элементом.
Замечание: проверка на пустое значение для разных типов данных проводится по-разному. Только для ссылочных типов данных можно ее осуществлять посредством метода Пустая().
Как получить массив номенклатурных позиций, использованных в табличных частях «Номенклатура» и «Тара» накладной?
Имеем ссылку на документ «СсылкаНаДокумент». Номенклатурные позиции могут быть указаны в колонке «Номенклат}фа» табличной части «Номенклатура» и в колонке «Номенклатура» табличной части «Тара».
Тогда массив номенклатуры из обеих табличных частей можно получить следующим образом:
|
МассивНоменклатуры = |
|
|
СсылкаНаДокумент.Номснклатура.ВыгруэитьКолонкуС’Номенклатура”): |
|
МассивНоменклатурыТара = |
|
|
СсылкаНаДокумент. ВозвратнаяТара.ВыірузитьК |
олонку(" Номенклатура”); |
|
Для Каждого ЭлементМассиваТара Из МассивНоменклатурыТара Цикл |
|
МассивНоменклатуры.Добавить( ЭлементМассиваТара); КонецЦикла; |
|
Формируем массив «МассивНоменклатуры» посредством выгрузки колонки «Номенклатура» табличной части «Товары» документа. Аналогично формируем массив «МассивНоменклатурыТара» по табличной части «Тара».
Далее в цикле перебора элементов второго массива добавляем их в первый.
Есть две таблицы значений. Как получить массив совпадающих имен колонок?
Данная операция может применяться для вспомогательного контроля перед загрузкой таблицы значений в таблицу записей регистра.
Итак, есть «ТаблицаИсточник» PI «ТаблицаПриемник», требуется получить массив имен совпадающих по имени колонок.
МассивСовпадающихКолонок = Новый Массив():
Для Каждого Колонка Из ТаблицаПриемник.Колонки Цикл МмяКолонкиПрисмника = Колонка.Имя:
Если ТаблицаИсточник.Колонки.Найти(ИмяКолонкиПриемника) о Неопределено Тогда
МассивСовпадающихКолонок.Добавить(ИмяКолонкиПрисмника):
КонецЕсли;
КонецЦикла;
Создаем сначала конструктором «МассивСовпадающихКолонок».
Далее выполняем цикл перебора колонок одной из таблиц. Внутри цикла в переменную «ИмяКолонки» получаем имя очередной колонки.
Далее обращаемся к коллекции колонок другой таблицы значений и при помощи метода Найти() пытаемся найти такую же по имени колонку. Если поиск успехом не увенчается - метод выдаст значение Неопределено. А если удалось - добавляем очередной элемент к массиву «МассивСовпадающихКолонок».
Как в запросе сделать отбор по нескольким вариантам заполнения реквизита типа «ПеречислениеСсылка»?
Одним из приемов программирования, использующим массивы, является формирование коллекции возможных значений для заполнения параметров запроса. Это выполняется, например, когда в запросе используются отборы с операндами В или В ИЕРАРХИИ.
Вот пример решения задачи:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
I ОтпускаОрганизацииРаботникиОрганизации.ФнзЛицо,
I ОтпускаОрганизацииРаботникиОрганизации.ДатаНачала.
I ОтпускаОрганизацииРаботникиОрганизации.ДатаОкончания |ИЗ
I Документ.ОтпускаОрганизации.РаботникиОрганизации КАК ОтпускаОрганизацииРаботникиОрганизации
|ГДЕ
I ОтпускаОрганизацииРаботннкиОрганизацни.ПричинаОгсутствия
В (&МассивПричин)'
МассивПрпчин = Новый Массив;
МассивПричин.ДобавитЫ Перечисления
.ПричиныОтсутствияНаРаботеВОрганизации
.ОтпускБезСохраненияЗарплаты);
МассивПричин.Добавить(Перечисления
.ПричиныОтсутствияНаРаботеВОрганизапии
.ОтпускУчебный);
Запрос.УстановитьПараметр("МассивПрпчин". МасснвПричин);
В параметр «МассивПричин» устанавливается значение - массив возможных причин, набранный из элементов перечисления « ПричиныОтсутствия».
Замечание: для решения подобных задач (с операндами В и В ИЕРАРХИИ) можно передавать не только данные типа Массив, можно еще СписокЗначениЙ или вообще сформировать коллекцию возможных значений вложенным запросом в самом тексте запроса. Вариант выбора заполнения параметра зависит от конкретики самой задачи.
Как из регистра сведений
«РасчетчикиЗарплатыОрганизации» получитьв виде массива всех расчетчиков зарплаты определенного подразделения организации?
Периодический независимый регистр сведений
«РасчетчикиЗарплатыОрганизации» имеет следующую структуру:
-ф РасчетчжиЗерплвтыОрганизеции Э - Измерения
М ¦ Паареэаелемие0рге»«43?ці*і В-f
m Ресурсы ! По/»>эомтель
}-§ Реквизиты
Данную задачу можно решить посредством применения методов объектной модели или запросом.
Пример решения посредством объектной модели:
Функция ПолучитьМассивРасчетчиков(Подразделение)
НаборЗаписей = РегистрыСведений
. Расчетч и киЗарплатыОрганизаци и .СоздатьНаборЗаписейО;
НаборЗаписей. Отбор. ПодразделениеОрганизации.Установить(Подразделение); НаборЗаписей. Прочитать));
МассивРасчетчиков = НаборЗаписей.ВыгрузитьКолонкуС'Пользователь”); Возврат МассивРасчетчиков;
КонецФункции
Создаем набор записей регистра. Устанавливаем отбор по значению измерения «ПодразделениеОрганизации».
Читаем данные набора записей.
Выгружаем колонку набора записей «Пользователь» в массив.
Пример решения задачи посредством запроса:
Функция ПолучитьМассивРасчетчиков(Подразделение)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
I РасчетчикиЗарплатыОрі анизацни.Пользователь КАК Расчетчик |ИЗ_
I РепістрСведенин.РасчетчикиЗарплатыОріанизацііи I КАК РасчетчикнЗарплатыОрганизации
ГДЕ
I РасчетчикиЗарплатыОрганизации.ПодразделениеОрі анизации =
&Подразделение'
Запрос.УстановитьПарамегрС'Подразделение". Подразделение);
Результат = Запрос.ВыиолнитьО;
Выборка = Результат.ВыбратьО:
МасснвРасчетчиков = Новый Массив;
Пока Выборка.Следующий() Цикл МассивРасчетчиков.Добавить(Выборка.Расчетчик);
КонецЦикла:
Возврат МасснвРасчетчиков;
КонсцФункции
Источником в запросе будет таблица регистра «РегистрСведений.РасчетчикиЗарплатыОрганизации». Накладываем отбор по условию равенства поля «ПодразделениеОрганизации» определенному значению.
В качестве выходных полей выбираем только «Пользователь».
После выполнения запроса делаем выборку по результату запроса и в цикле перебора ее - формируем нужный массив.
В данных примерах оба способа возвращают одинаковые результаты примерно за одинаковое время потому, что никаких дополнительных действий в процессе получения информации не требуется.
Второй способ на первый взгляд кажется более длинным в отношении написания кода.
Но если нам понадобится произвести отбор более чем по одному условию, или получить массив неповторяющихся значений — то вторым способом получить такие данные будет значительно легче и быстрее с точки зрения скорости исполнения.
Структура
® В каких ситуациях обычно используются объекты типа «Структура»?
Структура является универсальной коллекцией, то есть объектом, предназначенным для работы с не хранящимися в базе данных совокупностями значений.
Необходимость в ее использовании возникает, когда требуется работать с временным набором данных с чуть более сложной природой, нежели в массиве.
Если элемент массива можно было характеризовать только числовым индексом и значением произвольного типа, то элемент структуры характеризуется строковым ключом и значением произвольного типа.
Чаще всего структуры применяют в ситуациях, когда необходимо узнать или использовать имена реквизитов, свойств, полей, подчиненных объектов для тех или иных объектов; узнать или использовать значения реквизитов, свойств, полей, подчиненных объектов по их именам для тех или иных объектов.
Кроме того, структуры удобно использовать для передачи параметров при работе с различными объектами.
Структуры могут создаваться конструктором НОВЫЙ или получаться в результате применения методов некоторых объектов. Ввод элементов в структуру можно осуществлять как посредством параметров конструктора, так и посредством метода Вставить().
Как создать структуру?
Создание структуры чаще всего происходит посредством оператора
НОВЫЙ:
СозданнаяСтруктура = Новый Структура:
где «СозданнаяСтруктура» - имя переменной, которая будет содержать созданный объект типа Структура.
После вышеприведенного создания в структуру можно вставлять элементы (произвольное количество).
Если же мы хотим создать структуру с заранее определенными элементами - это можно сделать, например, так:
Оппонент = Новый Структура ("Фамилия, Имя, Отчество, Возрасг
"Иванов". "Иван”, "Иванович", 7);
Первым параметром передается строка, в которой через запятую перечисляются ключи элементов структуры. Остальные параметры содержат значения для элементов структуры в том же порядке, в котором были перечислены ключи.
Для такой структуры впоследствии можно обращаться к любому из элементов для записи или для чтения значения. А так же, при необходимости, к этой структуре можно еще добавлять новые элементы.
Как добавить элементы в структуру?
Для добавления элементов в структуру используется метод Вставить(). Первым параметром указывается ключ, вторым - значение нового элемента.
Замечание: если в составе структуры уже был элемент с подобным ключом - то старый элемент будет замещен новым.
Например:
|
Оппонент = Новый Структура ("Фамилия. Имя, Отчестве |
. Возраст", |
|
"Иванов", "Иван". "Иванович", 7); |
|
Оппонент.ВставитМ"Обращение", "Господин"); Оппонент.ВставитьС'Возраст", 25); |
|
Как обратиться к элементу структуры?
Для чтения значений элементов структуры можно использовать несколько вариантов написания кода.
Для структуры «Оппонент», в составе которой есть элемент с ключом «Возраст» можно использовать явное указание значения ключа:
ТекущийВозраст = Оппонет.Возраст:
или передачу ключа в переменной:
КлючСтруктуры = "Возраст";
Текущий Возраст = Опионет|КлючСтруктуры|
Также можно использовать метод СвоЙСТВО(), который получает значение элемента структуры по указанному ключу:
ТекушийВозраст = Неопределено; Опионет.СвойствоІ "Возраст". ТекушийВозраст)
Для записи значений элементов структуры также можно использовать несколько вариантов написания кода.
Если мы хотим изменить значение возраста в структуре из вышеописанного примера - можно это сделать так:
Оппонет. Возраст = 32
или так:
ОппонетІ"Возраст"! - 32:
или так:
Оппонент.Вставить("Возраст". 32):
Как перебрать элементы структуры?
Поскольку структура является коллекцией - перебрать элементы структуры можно посредством цикла перебора коллекции.
Например, чтобы сообщить обо всех ключах и значениях элементов структуры «СтруктураПараметров», можно сделать следующее:
Для Каждого Элемент из СтруктураПараметров Цикл СообщитьОлемент.Ключ + " + Элемент.Значение);
КонецЦикла;_
Как удалить элемент структуры?
Чтобы удалить элемент структуры - необходимо знать его ключ. Например, чтобы удалить из структуры «СтруктураПараметров» элемент с ключом «Номенклатура», достаточно сделать следующее:
СтруктураПарачетров.Удалить("Номенклатура''):
Если же нужно удалить все элементы структуры - применяется метод ОЧИСТИТЬ):
СтруктураПараметров. ОчиститьО;
Как в структуре установить значение для элемента с определенным ключом?
Все ключи элементов структуры - уникальны. Поэтому добавление новых элементов и замена (установка) значений для «старых» элементов выполняется одним и тем же методом Вставить
л):
|
|
|
Структура = Новый Структура:
// Добавить новый элемент.
Структура.ВставитЫ"Цвет". У?еЬЦвста.Белый);
// Установить значение для элемента с ключом "Цвет". Струкгура.ВставитьС'Цвег", ??еЬЦвега.Синий); |
|
Результатом примера выше будет структура, состоящая только из одного элемента: ключ у него - «Цвет», значение - «Синий» из системного набора значений \Л/еЬЦвета.
Как получить в структуру многомерные данные? Как собрать информацию по установленным в форме журнала отборам?
Для формы журнала документов установлены некие отборы. Чтобы сформировать многомерную структуру всех используемых отборов объекта «ЖурналДокументовСписок», можно сделать следующее:
СтруктураОтборов = Новый Структура:
СтрукгураПараметровОтбора = Новый Структура;
Для Каждого ЭлементОтбора из ЖурналДокументовСписок.Отбор Цикл Если ЭлементОтбора.Использованне Тогда СтруктураПараметровОтбора.ОчиститьО;
СтруктураПараметровОтбора.ВставитьС'Имя", ЭлементОтбора.Имя); СтруктураПараметровОтбора.ВставитьС'ВидС равнения”.
ЭлементОтбора.ВидСравнення);
СтруктураПараметровОтбора.Вставить) "Значение", ЭлементОгбора.Значение): СтруктураПараметровОтбора.ВставитьСЗначениеПо",
ЭлементОтбора.ЗначениеПо);
СтруктураПараметровОтбора.Вставить) "ЗначениеС". ЭлементОтбора.ЗначениеС); СтруктураПарамстровОтбора.ВставитьС'Представление".
ЭлементОтбора.Представление);
СтруктураПараметровОтбора.ВсгавитьС'ПутьКДаиным",
ЭлементОтбора.ПутьКДанным); СтрукгураПараметровОтбора. Вставить) "Т ипЗначения".
ЭлементОтбора.ТипЗначения);
СтруктураОтборов.ВставитыЭлементОтбора.Имя, СтрукгураІІараметровОгбора):
КонецЕсли:
КонецЦикла:
Создаем конструкторами две структуры. Структура «СтруктураОтборов» впоследствии будет содержать элементы, где в качестве ключа будет указано название отбора, а в качестве значения -« СтрукгураПараметровОтбора».
В цикле перебора коллекции отборов объекта «ЖурналДокументовСписок» сначала проверяем, используется ли данный отбор. Если используется — заполняем структуру параметров данного отбора. Полученную структуру используем в качестве значения добавляемого элемента объекта «СтруктураОтборов».
Впоследствии, если нам потребуется информация из полученной структуры, можно будет, например, перебрать элементы
«СтруктураОтбора», а для каждого из этих элементов - перебрать элементы ее значения - структуры «ПараметрыОтбора»
Как определить, есть ли в структуре элемент с ключом «Контрагент», и если есть, но содержит пустое значение справочника или Неопределено - удалить этот элемент?
Если Структура.СвойствоСКонтрагент". ЗначениеЭлемента) Тогда Если ЗначениеЭлемента = Неопределено или ЗначениеЭлсмеита.Пустая() Тогда Структура.УдалитьСКонтрагент");
КонецЕсли;
КонецЕсли;
В качестве параметров метода СВоЙСТВО() можно указать ключ и переменную для получения значения по ключу.
Кроме того, сам метод возвращает Истина, если элемент с данным ключом существует, и Ложь - если нет.
Получив значение и проверив его на требуемые условия, удаляем элемент с указанным ключом из структуры.
Замечание: кроме метода СВоЙСТВО() получить значения элемента структуры позволяют следующие варианты обращения по ключу:
Структура-Контрагент или
Структура[ "Контрагент"
Как из табличной части «Товары» документа получить все строки, где значение реквизита «Цена» равно нулю, а значение реквизита «СтавкаНДС» равно значению «НДС18» перечисления «СтавкиНДС»?
Для поиска строк, соответствующих условию определенного отбора, можно сделать следующее:
СтруктураДляПоиска = Новый Структура(”Цена, СтавкаНДС”,
О, Перечисления.СтавкиНДС.НДС18); МассивСтрок = Товары. НайтиСтроки(СтруктураДляПоиска);
Сначала создаем структуру для поиска. Далее посредством метода НаЙТиСтр0КИ() из табличной части документа «Товары» получаем массив строк, соответствующих отбору по структуре поиска.
Обратите внимание, в данном примере был показан вариант добавления и заполнения элементов структуры непосредственно в конструкторе.
Как получить данные о текущей учетной политике бухгалтерского учета организации из периодического регистра сведений на заданную дату?
Периодический регистр сведений
«УчетнаяПолитикаБухгалтерскийУчет» имеет следующую структуру:
У^наяЛо/мтикаБухга/тгерскийУ-Й \ ¦ Измерения
¦ Организация й _ Ресурсы
і СпособО ценкиМ П 3 ¦— J ДфектКостинг s Реквизиты
Тип значения измерения «Организация»
СправочникСсылка. Организации.
Ссылка на организацию находится в переменной «ЮрЛицо». Дата, на которую необходимо получить данные - переменная «ДатаПолучения».
Получение необходимых данных можно организовать посредством метода ПолучитьПоследнее() менеджера регистра:
// Подготовить отбор но измерению "Организация".
СтруктураОтбора = Новый Структура("Организация". ЮрЛицо);
// Получить данные, актуальные на указанную дату.
СтруктураДанных = РегистрыСведений
.УчетнаяПолитикаБухгалтсрскийУчет .ПолучитьПоследнее(ДатаПолученіія. СтруктураОтбора):
// Прочитать данные из структуры данных.
СпособОцснкиМнзЮрЛица = СтруктураДанных.СнособОцснкиМПЗ: ДиректКоетингЮрЛица - СтруктураДанных.ДиректКосгнт;_
Метод предназначен для получения данных наиболее поздней записи регистра, соответствующей указанным периоду и значениям измерений регистра.
Значения измерений регистра должны предаваться в виде структуры. Каждый элемент структуры в качестве ключа должен использовать имя измерения. В качестве значения элемента структуры передаем значение отбора по этому измерению.
Дату получения и полученную структуру отбора используем в качестве параметров для метода ПолучитьПоследнее(). Результатом применения метода к периодическому регистру сведений «УчетнаяПолитикаБухгалтерскийУчет» будет структура. Элементы полученной структуры состоят из названия ресурса в качестве ключа и значения ресурса в качестве значения.
Каксформировать структуруназваний реквизитов табличной части произвольного документа?
Пример функции, решающую данную задачу - ниже. В качестве параметров необходимо передать ссылку на документ и имя табличной части документа.
Функция СформировагьСтрукгуруТаблнчнойЧастиДокумента(Документ,
ИмяТабличнойЧасти)
СтруктураТабличмойЧастиДокумента = Новый Структура;
Для Каждого Реквизит из Документ
.МстаданнысО
.ТабличныеЧасти[ИмяТабличнойЧасти1 .Реквизиты Цикл
С трукгураТабличнойЧастиДокумента. Вставить) Реквизит. Имя, Реквизит.Имя); КонецЦикла;
Возврат СтруктураТабличнойЧастиДокумента;
КонецФункции
Конструктором создаем структуру
« Стру ктураТабл ичнойЧастиДокумента».
В цикле перебора реквизитов нужной табличной части полученного документа вставляем в структуру элементы с названиями полученных реквизитов.
Замечание: значения элементам структуры можно было и не указывать - все зависит от того, как в дальнейшем собираемся использовать полученную структуру.
Как получить запросом данные табличной части документа, имея структуру названий реквизитов табличной части?
Пример функции, решающей данную задачу - ниже. В качестве параметров необходимо передать ссылку на документ или объект документа, имя табличной части и структуру названий реквизитов этой табличной части.
Функция основана на сборе информации запросом, чей текст собирается «кусочками» из строковых переменных:
Функция СформироватьЗапросПоТабличнойЧасти(Документ.
ИмяТабличнойЧасти, СтруктураПолей) Экспорт
ПоляРеквизитов =
Для Каждого Реквизит Из СтруктураПолей Цикл
ПоляРеквизитов = Поля Реквизитов 4 ",
ІДок.” 4 Реквизит.Значение 4
?(ЗначенисНсЗаполнено(Рсквизиі.Ключ), " КАК " 4 СокрЛП(Реквизит.Ключ));
КоиецЦикла:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ I Док.НомерСтроки ” 4 ПоляРеквизитов 4 "
|ИЗ
I Документ."
4 Документ.МетаданныеО.Имя 4 ".”4 СокрЛП(ИмяТабличнойЧасти) 4 " КАК Док
ГДЕ Док.Ссылка = &ДокументСсылка":
// Установить параметры запроса.
Запрос.УстановитьПараметрС'ДокументСсылка", Доку мент.Ссылка) Возврат Запрос.ВыполнитьО:
КонецФункции
Создаем переменную «ПоляРеквизитов».
В цикле перебора элементов структуры имен полей табличной части добавляем к переменной «ПоляРеквизитов» «по кусочкам» будущие имена выходных полей запроса. Добавляются они через запятую.
Далее формируем запрос, к тексту которого добавляем строку имен выходных полей запроса.
Источником указываем таблицу нужной табличной части нужного документа. Кроме того, накладываем отбор по полю «Ссылка».
Функция возвращает результат выполнения запроса.
Соответствие
ф В каких ситуациях обычно используются объекты типа «Соответствие»?
Соответствие является универсальной коллекцией, то есть объектом, предназначенным для работы с не хранящимися в базе данных совокупностями значений.
Необходимость в его использовании возникает, когда требуется работать с временным набором данных с чуть более сложной природой, нежели в структуре.
Если элемент структуры можно было характеризовать только строковым ключом и значением произвольного типа, то элемент соответствия характеризуется ключом произвольного типа и значением произвольного типа.
Чаще всего соответствия применяют в ситуациях, когда необходимо хранить в оперативной памяти для последующей обработки данные с ключами произвольного типа.
Кроме того, соответствия удобно использовать для передачи параметров при работе с различными объектами.
Соответствия могут создаваться конструктором НОВЫЙ.
ф Как создать соответствие?
|
Создание соответствия происходит посредством оператора Новый: |
г ?оз іаннос?оотвеіствие = Цовыц ^oibcicibmcQ
I С .ло. )дап н ?те? Сол V 1 веЗс 1 КПе 1 І?овТ>йГ С-А/оІИетс івТТеі |
|
|
|
|
|
где «СозданноеСоотвелствие» - имя переменной, которая будет содержать созданный объект типа Соответствие.
После вышеприведенного создания в соответствие можно вставлять элементты ((произвольное жопиввслво).
ф Как добавить элементы в соответствие?
Допустим к соответствию «ВозрастСотрудников»- нужно добавить новый элемент. В качестве ключа должна выступать ссылка на сотрудника (ее можно считать из переменной «Сотрудник»), в качестве значения - возраст сотрудника (его можно считать из переменной «ВозраслСощрудшиі&ві»).
Тогда добавление нового элемента можно произвести так: ВозрастСотрудников.ВставитьіСозрудник, ВозрастСотрудника);
или так:
ВозрастСотрудннков [Сотрудник] = ВозрастСотрудника;
Как обратиться к элементу соответствия?
Запись значений элементов соответствия можно выполнять теми же способами, которые рассмотрены в вопросе «Как добавить элемент в соответствие?» на странице 57.
А чтение значений элементов соответствия можно выполнять следующим образом:
ВозрастСотрудника = ВозрастСотрудников.Получнті.(Сотрудник);
или так:
ВозрастСотрудника = ВозрастСотрудннков [Сотрудник]
В приведенных примерах из соответствия «ВозрастСотрудников» по ссылке на сотрудника в качестве ключа будет получено значение элемента соответствия.
Как перебрать элементы соответствия?
Поскольку соответствие является коллекцией - перебрать элементы соответствия можно посредством цикла перебора коллекции.
Например, чтобы сообщить обо всех ключах и значениях элементов соответствия «Замены», можно сделать следующее:
Для Каждого Элемент из Замены Цикл СообщитЦЭлемент.Ключ + " -" + Элемент.Значение) КонецЦикла;
Как удалить элемент соответствия?
Чтобы удалить элемент соответствия - необходимо знать его ключ. Например, чтобы удалить из соответствия «Замены» элемент со ссылкой на объект, содержащийся в переменной «УдаляемыйТовар», в качестве ключа, достаточно сделать следующее:
Замены.Удал ит ь(УлаляемыйТовар):
Если же нужно удалить все элементы соответствия — применяется метод ОЧИСТИТЬ):
Замены. ОчиститьО;
Как получить данные из соответствия?
В соответствии «КурсыВалютДокумента» в качестве ключа используется значение валюты, а значениями являются структуры, содержащие «Курс» и «Кратность». Как получить курс и кратность валюты «УправленческаяВалюта» ?
Значение = КурсыВалютДокумента. Получить! У правленческая Валюта)
Если Значение = Неопределено Тогда Сообщить!"Данпая валюта в соответствии отсутствует");
Иначе
Курс = Значение["Курс"];
Кратность = Значение("Кратность"];
КонецЕсли;
Сначала по ключу (ссылке на управленческую валюту) получаем значение соответствия. Поскольку значением является структура курса валют - далее получаем значения структуры по их названиям.
Как получить многоуровневое соответствие видов расчетов, обладающих базовыми видами расчетов?
Для плана видов расчетов «ОсновныеНачисления» необходимо получить соответствие «ВидыРасчетов», где в качестве ключей будут использоваться виды расчетов, обладающие базовыми. А в качестве значений - соответствия базовых видов расчетов. В качестве ключей последних - базовые виды расчета, в качестве значений - структуры, содержащие их свойства «Наименование» и «Предопределенный».
|
Виды расчета |
Базовые виды расчета |
Свойства базового вида расчета |
|
|
Оклад по дням |
"Наименование" - "Оклад по дням" |
|
|
"Предопределенный" - Истина |
|
|
Оклад по часам |
"Наименование" - "Оклад по часам" |
|
|
"Предопределенный" - Ложь |
Ежегодный
отпуск |
Оплата по часовому т арифу |
"Наименование" -"Оплата по часовому тарифу" |
|
"Предопределенный" - Ложь |
|
Оплата по дневному тарифу |
"Наименование" -"Оплата по дневному тарифу" |
|
|
"Предопределенный" - Истина |
|
|
Оплата по произволе твенным нарядам |
"Наименование" -
"Оплата по производственным нарядам" |
|
|
"Предопределенный" - Истина |
|
|
Оклад по дням |
"Наименование" - "Оклад по дням" |
|
|
"Предопределенный" - Истина |
|
Надбавка за в редность |
Оклад по часам |
"Наименование" - "Оклад по часам" |
|
"Предопределенный" - Ложь |
|
Оплата по произволе твенным нарядам |
"Наименование" -
"Оплата по производственным нарядам" |
|
|
"Предопределенный" - Истина |
Первичный сбор информации удобнее осуществить при помощи запроса с использованием итогов. Последующий перебор группировок результат запроса даст возможность сформировать необходимые объекты:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
I ОсновныеНачисленияОрганіпацинБа-ювыеВидыРасчета.Ссылка КАК Ссылка,
I ОсновныеНачисленняОріаничацииБаювыеВидыРасчета.ВидРасчега, |ОсновныеНачисленияОрганизацииБачовыеВидыРасчеіа.ВидРасчета. Наименование.
I ОсновнысНачисленияОрганизацииБазовыеВилыРасчета.Предопределенный |ИЗ
I ПланВидовРасчета.ОсновныеНачисленияОрганизации.БазовыеВидыРасчета КАК ОсновныеНачисленияОрганизацииБазовыеВидыРасчега
ІИТОГИ ПО
Ссылка":
Результат = Запрос.ВыполнитьО;
ВыборкаВидовРасчета = Результат
. Выбрать(ОбходРезульта таЗапроса. ПоГру ппировкам): ВидыРасчета = Новый Соответствие;
БазовыеВидаРасчета = Новый Соответствие;
СвойстваВидаРасчега = Новый СтруктураС'Наименование, Предопределенный"):
// Цикл по видам расчета, обладающим базовыми.
Пока ВыборкаВндовРасчета.СледующийО Цикл БазовыеВидаРасчета.ОчиститъО;
ВыборкаБазовых = ВыборкаВидовРасчета
.Выбрать(ОбходРезультатаЗапроеа.ПоГруппнровкам);
// Цикл по базовым видам расчета.
Пока ВыборкаБазовых.СледующийО Цикл
И Заполненить значения структуры "СвойстваВидаРасчета". СвойстваВндаРасчета.Наименование = ВыборкаБазовых.Наименование: СвойстваВидаРасчета.Предопределенный = ВыборкаБазовых
.Предопределенный;
// Заполненить соответствие "БазовыеВидАРасчета”. БазовыеВидаРасчета. Вставить(Выборка Базовых. ВидРасчета.
СвойстваВидаРасчета);
КонецЦикла:
// Заполнить соответствие "ВидыРасчета".
ВіиыРасчета.Вставить! ВыборкаВидовРасчста.Ссылка. БазовыеВидаРасчета); КонецЦикла;
Для запроса источником является таблица
«ПланВидовРасчета.ОсновныеНачисленияОрганизации.БазовыеВидыРас чета». Выходными полями делаем все, необходимые для решения нашей задачи.
Кроме того, вводим дополнительные итоги по полю «Ссылка» (ссылка на виды расчета).
После выполнения запроса делаем выборку по верхнему уровню группировок результата запроса.
Создаем конструктором три объекта - соответствие «ВидыРасчетов», в которое будем впоследствии добавлять виды расчетов, обладающие базовыми; соответствие «БазовыеВидыРасчетов», в которое будем добавлять базовые виды расчетов для каждого отдельного вида (владельца); структуру «СвойстваВидовРасчетов» для добавления информации о свойствах базовых видах расчетов.
В цикле перебора верхнего уровня группировок (по видам расчета) сначала очищаем соответствие «БазовыеВидыРасчета».
Далее открываем цикл перебора записей второго уровня группировки результата запроса (то есть уже по базовым видам расчетов определенного владельца). В этом цикле заполняем значения структуры «СвойстваВидовРасчетов» по ключам - названиям свойств. Далее добавляем сформированные структуры в качестве значений соответствия «БазовыеВидыРасчета» с конкретным базовым видом расчета в качестве ключа.
По окончании вложенного цикла добавляем очередной элемент в соответствие «ВидыРасчетов» с заполнением значения ключа из поля «Ссылка», и заполненным соответствием «БазовыеВидыРасчета» в качестве значения.
Список значений, таблица значений, дерево значений
® В каких ситуациях обычно используются списки значений, таблицы значений, дерево значений?
Все эти объекты являются универсальными коллекциями, то есть объектами, предназначенным для работы с не хранящимися в базе данных совокупностями значений.
Необходимость в использовании списка значений возникает, когда требуется работать с временным набором данных для решения интерфейсных задач. Дело в том, что в отличие от более простых универсальных коллекций (массива, структуры, соответствия) список значений состоит из объектов - ЭлементСпискаЗначениЙ. А элемент списка значений характеризуется следующим набором свойств:
• Значение;
• Представление. Содержит строковое пользовательское представление. То есть именно его пользователь увидит на экране. По умолчанию - генерируется автоматически;
• Пометка;
• Картинка;
Применение списков значений для обычных задач универсальных коллекций, но не связанных с интерфейсными действиями, как правило - излишне. Обычно с этой функциональностью справляются объекты «попроще»: Массив, Структура, Соответствие.
Таблицы значений позволяют работать с данными сущностей, представимых в виде таблиц, то есть «раскладываемых» на колонки и строки. А ведь с точки зрения многих систем автоматизации вообще «весь мир = совокупность таблиц».
При этом можно добавлять/удалять данные (и колонки, и строки, и значения); искать данные (и колонки, и строки, и значения); сортировать данные (по любым колонкам); выгружать-загружать данные; подсчитывать итоги по колонкам; сворачивать данные и т.д.
Дерево значений позволяет в добавление к вышеприведенным операциям еще вводить уровни иерархии для этих данных и оперировать в пределах уровней или игнорируя их.
Подобный набор возможностей помогает решать самый широкий спектр задач промежуточной обработки данных произвольного типа.
Как создать список значений?
Список значений можно создать посредством оператора НОВЫЙ:
СотданныйСиисок = Новый СписокЗначений:
где «СозданныйСписок» - имя переменной, которая будет содержать созданный объект типа СписокЗначении.
Как добавить элементы в список значений?
Например, требуется добавить в список значений «СписокСотрудников» новый элемент со значением ссылки на сотрудника (содержится в переменной «ТекущийСотрудник»), ФИО сотрудника в качестве представления (содержится в реквизите «ФИО» объекта «ТекущийСотрудник») и фотографии сотрудника в качестве картинки (содержится в переменной «Фото»):
СписокСотрудников.Добавить(ТекущийСотрудник.
ТекущийСотрудник.ФИО.
Фото):
Если нужно, чтобы новые значения добавлялись с определенным индексом (переменная «Инд»), то можно использовать метод
Вставить():
СписокСотрудников. Вставить(Инд,
ТекущийСотрудник.
ТекушийСотрудник.ФИО
Фото);
Если при этом в списке значений уже был элемент с таким индексом, то старый элемент получит индекс на единицу больше предыдущего; аналогично сдвинуться индексы у всех последующих.
Если при использовании метода Вставить() указать индекс, выходящий за границы списка, - получим сообщение об ошибке.
Как найти элемент списка значений?
Например, в списке значений «СписокСотрудников» надо найти элемент, в котором в качестве значения указан сотрудник, на которого ссылается переменная «ИскомыйСотрудник». Затем нужно сообщить индекс найденного элемента.
Это можно выполнить следующим образом:
ЭлементСписка = СішсокСотрудников.НайтиПоЗначению(ИскомыйСотрудннк);
Если ЭлементСписка о Неопределено Тогда Сообшить(СписокСотрудннков.Индекс(ЭлементСписка));
КонецЕсли;
Замечание: если искомое значение в списке может встретиться несколько раз - при таком подходе найдем только первый элемент, где оно содержится.
Поэтому смотрите по ситуации. Поскольку список значения - объект, предназначенный, прежде всего для визуализации возможностей выбора пользователем, обычно при его заполнении уже сразу предотвращают возможность повторов.
Если же такая возможность осмыслена, то получить все элементы списка значений, содержащие определенное значение можно, например, в цикле перебора элементов списка значений.
Как обратиться к элементу списка значений?
Если требуется получить доступ к элементу списка значений с определенным индексом (пусть содержится в переменной «Инд»), можно поступить так:
ЭлементСписка = СписокСотрудников! Инд]
или так:
ЭлементСписка = СписокСотрудников.Получить(Инд):
В любом случае - то, что получаем, еще не есть значение, заложенное в этот элемент списка (это еще не сотрудник), а именно объект типа ЭлементСпискаЗначений.
Впоследствии с него можно считать значения свойств:
Сотрудник = ЭлемснтСписка.Значение; Представление = ЭлеменчСписка.Представление: Пометка = ЭлементСпнска.Пометка;
Картинка = ЭлементСписка.Картинка:
Как перебрать элементы списка значений?
Поскольку имеем дело с индексированной коллекцией, то можно использовать цикл перебора элементов коллекции или «цикл-счетчик».
Например, чтобы сообщить значения всех элементов списка значений «СписокСотрудников», можно использовать следующий код:
Для Каждого ЭлементСписка Из СписокСотрудников Цикл Сообщить(ЭлементСписка.Значение):
КонсцЦикла;
То же через «цикл-счетчик»:
Старшин Индекс = СписокСотрудников.Количество!) - 1
Для Сч = 0 по СтаршийИндекс Цикл Сообщить(СписокСотрудннков[Сч].Значение): КонецЦикла;
Как удалить элемент списка значений?
Удаление отдельных элементов списка значений происходит с обязательным указанием индекса удаляемого элемента. Так, например, будет удален первый элемент массива:
СписокСотрудников.Удалить(О);
Естественно, если указанный индекс будет выходить за границу индексов списка - получим сообщение об ошибке.
Кроме того, необходимо учитывать, что удаление элемента «из середины» списка приведет к уменьшению на единицу индексов элементов, стоявших «после» удаленного. Список значений - «сомкнет ряды».
Решим задачу удаления всех элементов списка значений «СписокОбъектов», содержащих числовые значения:

Сначала определяем самый старший индекс элементов списка значений. Цикл проверок и удалений элементов будет выполняться, пока очередное значение индекса не окажется меньше нуля.
В цикле определяем тип значения элемента с текущим индексом. Если это число - удаляем данный элемент. Кроме того, в любом случае уменьшаем на единицу значение переменной «Индекс».
В результате, поскольку перебор элементов списка значений производится с конца, то эффект «смыкания рядов» будет актуален только для уже проверенных элементов.
ф Как создать таблицу значений и заполнить ее поля?
Для создания таблицы значений используется оператор Новый:
Табл и цаЗначс н и н = Новым Табл ицаЗначс ним
После этого молено создать колонки таблицы (при необходимости можно задать допустимые типы значений для колонки, заголовок и ширину колонки в символах).
И Создать нужные колонки. ТаблицаЗначений.Колонки.ДобавитьС'Фамилия") ТаблішаЗначсний. Колонки. ДобавитьС Возраст"):
Затем можно добавить новую строку и установить значения в колонках таблицы:
II Добавить новую строку и задать значения в колонках таблицы НоваяСтрока = ТаблицаЗначений.ДобавитьО; НоваяСтрока.Фамилия = "Иванов";
НоваяСтрока.Возраст = 23;
или так:
// Добавить новую строку и задать значения в колонках таблицы НоваяСтрока = ТаблицаЗначений.ДобавитМ);
НоваяСтрока| "Фамилия"] = "Иванов":
НоваяСтрока[”Возраст"] = 23;
Как найти значение в таблице значений?
Если требуется найти первую строку таблицы значений «ТаблицаЗначений», где присутствует «ИскомоеЗначение», можно сделать так:
I Навдгн наяСтрока = ТаблинаЗначенийНаши(ИскомоеЗначение);
Если требуется найти первую строку, где «ИскомоеЗначение» может быть найдено, например, в колонках «Поставщик» и «Покупатель», то:
НайденнаяСтрока = ТаблицаЗначений.Найти! ИскомоеЗначение,
"Поставщик, Покупатель");
Если же нужно найти все строки, где в колонке «Сотрудник» присутствует искомое значение, то это можно выполнить при помощи метода НаЙТиСтроки():
// Сформировать структуру отбора.
СтруктураПоиска = СтруктураС'Сотрудннк". ИскомоеЗначение);
// Найти строки.
МассивНайденныхСтрок = ТаблицаЗначений.НайтиСтроки(СтруктураПоиска);
Сначала создаем структуру поиска, каждый элемент которой будет содержать название колонки таблицы значений в качестве ключа и искомое значение в этой колонке - в качестве значения. Далее структуру поиска передаем в качестве параметра методу НаЙТиСтроки(). Результат - массив строк таблицы значений, соответствующих структуре поиска.
Замечание: если в этом примере в структуру поиска добавить поиск-нужного значения, например, еще и в колонке «Ответственный» - то в результате применения метода НаЙТиСтроки() получим все строки, где и «Сотрудник» и «Ответственный» равны искомому значению.
Как перебрать строки таблицы значений?
Поскольку имеем дело с индексированной коллекцией, то можно использовать цикл перебора элементов коллекции или «цикл-счетчик».
Например, чтобы сообщить значения колонки «Сотрудник» всех строк таблицы значений «ТаблицаСотрудников», можно использовать следующий код:
Для Каждого ТекущаяСтрока Из ТаблицаСотрудников Цикл Сообщить) ТекущаяС і рока.Сотрудник);
КонецЦикла:
То же через «цикл-счетчик»:
СтаршийИндекс = ТаблицаСотрудников.КоличествоО - 1
Для Сч = О по СтаршийИндекс Цикл Сообщить(СпнсокСотрудников[Сч].Сотрудник); КонецЦикла;
® Какудалить строки (колонки)таблицы значений?
Удаление отдельных строк таблицы значений происходит с обязательным указанием удаляемой строки или индекса удаляемой строки.
Если нужно удалить строку «УдаляемаяСтрока», входящую в таблицу значений «ТаблицаЗначений»:
ТаблицаЗначеннй.Удалить(УдаляемаяСтрока):
А так, например, будет удалена первая строка таблицы значений:
ТаблнцаЗначсннй.Удалнть(О):
Естественно, если указанный индекс будет выходить за границу индексов строк таблицы значений - получим сообщение об ошибке.
Аналогично и для колонок. Только работать уже надо с коллекцией колонок таблицы значений. Доступ к ней - через свойство КОЛОНКИ таблицы значений.
ТаблицаЗначений.Колонки. Удалить! Удаляемая Колонка)
или
ТаблицаЗначений.Колоики.Удалить(О);
Кроме того необходимо учитывать, что удаление строки (или колонки) «из середины» таблицы значений приведет к уменьшению на единицу индексов строк, стоявших «после» удаленной (эффект «смыкания рядов», вернее -«смыкание строк»).
Например, решим задачу удаления всех строк таблицы значений «ТаблицаЗначений», содержащих числовые значения хотя бы в одной колонке:
СтаршийИндексКолонок = ТаблицаЗначений.Копонки.КодичествоО - 1; Индекс = ТаблицаЗначений.Количество!) - 1;
Пока Индекс >= 0 Цикл
Для Сч = 0 По СтаршийИндексКолонок Цикл Если ТипЗнч(ТаблицаЗначений|Индскс][Счр = Тип('Число") Тогда ТаблицаЗначений. Удалить! Индекс);
Прервать;
КонецЕсли:
КонсцЦикла;
Индекс = Индекс - 1;
КонсцЦикла;
Сначала определяем самые старшие индексы строк и колонок таблицы значений. Цикл проверок и удалений строк будет выполняться, пока очередное значение индекса строки не окажется меньше нуля.
Внутри цикла но строкам делаем цикл-счетчик перебора индексов колонок.
Во вложенном цикле определяем тин значения элемента находящегося в строке с текущим индексом и в очередной колонке. Если это число - удаляем строку таблицы значений и прерываем вложенный цикл.
Кроме того, в любом случае на каждом шаге внешнего цикла уменьшаем на единицу значение переменной «Индекс».
В результате, поскольку перебор строк таблицы значений производится с конца, то эффект «смыкания рядов» будет актуален только для уже проверенных элементов.
Какзаполнитьтаблицузначений,если имена колонок содержатся в переменных?
Если имя колонки, для которой требуется установить значение, содержится в переменной, можно использовать оператор [ ]:
НоваяСтрока = Таблица'Значений Добавит ь(); НоваяСтрока|ИмяКолонкм] = Значение;
В вышеприведенном коде:
«ТаблицаЗначений» - имя таблицы значений;
«ИмяКолонки» - строковая переменная, содержащая имя колонки, по которой нужно заполнить значение;
«Значение» - переменная, содержащая само заполняемое значение.
Как заполнить всю колонку таблицы значений нужным значением?
Колонку «ФлагФискального Учета» в таблице значений
«ТаблицаЗначений» необходимо заполнить значением Ложь.
ТаблицаЗначений.ЗанолнитьЗначенияСЛожь. "ФлагФискальногоУчета"):
Применяем для таблицы значений метод ЗаполнитьЗначения(). Первым параметром передаем заполняемое значение. Вторым параметром - имя заполняемой колонки.
Как таблицу значений «ТаблицаПолучатель» заполнить данными таблицы значений «ИсходнаяТаблица»?
Замечание: если нужно заполнить несколько колонок значением - их имена указывают через запятую во втором параметре. Если не указать второй параметр - значением заполнятся все поля таблицы.
Если «ТаблицаПолучатель» на момент выполнения операции еще не существует, или ее предыдущие колонки сохранять не нужно, можно создать ее, как полную копию исходной:
ТаблицаПолучатель = ТаблицаИсхолная.Скопировать!)
Вариант второй: таблица «ТаблицаПолучатель» существует, и жалко терять ее колонки и ограничения на типы данных колонок. Но нужно заполнить данные по колонкам, имена которых совпадают с именами исходной таблицы.
Тогда можно так:
Для Каждого СтрокаИсходнойТаблицы Из ИсходнаяТаблица Цикл Новая Строка = ТаблицаПолучатель.Добавить(); ЗаполнитьЗначеішяСвойств! НоваяСтрока. СтрокаИсходнойТаблицы) КонецЦикла:
Для каждой строки исходной таблицы добавляется новая строка в таблицу получатель и выполняется заполнение значений в тех колонках новой таблицы, имена которых совпадают с именами колонок в исходной таблице.
Замечание: если у таблиц не будет колонок с одинаковыми именами - таблица-получатель будет в результате содержать столько же строк с пустыми значениями, сколько строк было в таблице-источнике.
Если у каких-то одноименных колонок тип значения данных из таблицы-источника не попадет в массив разрешенных типов колонки таблицы-получателя - в таких полях получим пустые значения.
Рассмотрим третий случай. В случае одноименных колонок - колонку таблицы-получателя нужно привести в полное соответствие колонке таблицы-источника.
ОдноимсннысКолонки = Новый Массив!):
Для каждого Колонка Из ИсходнаяТаблица.Колонкн Цикл СовпадающаяКолонка = ТаблицаПолучатсль.Колонкн.Найти(Колонка.Имя)
Если СовпадающаяКолонка о Неопределено Тогда // Получить свойства колонки.
Индекс = ТаблнцаПолучатель. Колонки. Нндекс<СовпадаюшаяКолонка); Имя = Колонка.Имя:
ТипЗначсния = Колоика.ТипЗначення;
Заголовок = Колонка. Заголовок;
Ширина = Колонка.Ширииа:
// Заменить колонки в таблице-получаетеле.
ТаблнцаПолучатель. Колонки. Удал ить( Индекс); ТаблицаПолучатель.Колонки.Вставить(Индекс.
Имя,
ТипЗначения,
Заголовок.
Ширина):
//Добавить очередное имя совпадающих колонок в массив. ОдноименныеКолонки .Добавить) Колонка. Имя);
КонецЕсли:
КонецЦикла;
// Цикл перебора строк исходной таблицы.
Для каждого СтрокаИсходнойТаблицы Из ИсходнаяТаблица Цикл
// Добавить новую строку в таблицу-получатель.
НоваяСтрока = ТаблицаПолучатель.Добавить();
// Заполнить значения в совпадающих ячейках.
Для каждого ИмяКолонки Из ОдноименныеКолонкн Цикл
НоваяСтрока|ИмяКолонкн| = СтрокаИсходнойТаблицы! ИмяКолонки): КонецЦикла:
КонецЦикла:
Нам придется заменить колонку в таблице получателе на новую, чьи свойства полностью будут соответствовать колонке таблицы-источника.
Поэтому в случае обнаружения в таблице-получателе одноименной колонки собираем в переменных все свойства для новой колонки. Далее удаляем старую и создаем новую колонку.
Далее выполняем цикл перебора строк исходной таблицы.
В цикле добавляем к таблице-получателю новую строку и открываем цикл перебора имен колонок в массиве совпадающих колонок.
Внутри этого вложенного никла производим заполнение ячеек таблицы получателя данными ячейки таблицы-источника.
Как добавить колонки к таблице значений «ТаблицаЗначений» с ограничениями по типу?
При добавлении колонки можно просто указать ее имя, а второй параметр метода Добавить() - не трогать. В этом случае тип данных колонки - произвольный.
//Добавить колонку без ограничений по типу. ТаблицаЗначений. Колонки. ДобавитМ "Объект");
Можно заполнить значение второго параметра. Туда необходимо передавать описание разрешенного для колонки типа. Само описание можно получить при помощи конструктора, передав последнему в качестве параметра строковое название типа (если много типов - через запятую) или массив допустимых типов.
// Ограничения но типам данных колонки:
//Только элементы справочника "Контрагенты
1’.
ТаблицаЗначений
.Колонки
.Добавить! "Контрагент”,
Новый ОписаниеТиповССправочникСсылка.Контраіенты"))
Если среди типов разрешенных к заполнению данных колонки есть строка - можно ограничить ее разрядность (длину), указать использование неременной или фиксированной длинны. Все это обеспечивается созданием объекта при помощи конструктора КвалификаторыСтроки. Далее этот объект будет использован в качестве одного из параметров конструктора ОписаниеТипов.
// Подготовка и установка оіраничсний для данных типа Строка. КвалификаторыСтроки = Новый КвалификаторыСтроки! 20,
Допустимая/ Ілина. Переменная);
ДопустимыеТнпы = Новый ОнисаниеТиіюв("Строка".. КвалификаторыСтроки); ТаблицаЗначений. Колон ки.Добавить("ПримечанисСтроковоеКороткое”,
Допу сти м ыеТи п ы):
Аналогичные действия можно осуществлять в отношении квалификаторов числа и даты.
Обратите внимание, описание типов можно строить конструктором как «с нуля», так и использовать как основу уже существующее описание типов.
// Расширение уже использованного ранее описания типов.
КвалификаторыЧисла = Новый КвалификаторыЧисла(Н), 2,
ДопустимыйЗнак. Неотрицательный): КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДаты.Дата); РасшпреннысДопустимыеТипы = Новый ОписанисТипов(ДопустимыеТипы.
"Число. Дата",, КвалификаторыЧисла., КвалификаторыДаты);
ТаблицаЗначений.Колонки.ДобавитьС'Прнмечание".
РасшнренныеДопустимысТ ины);
Какизменитьтип значения колонкитаблицы значений, полученной выгрузкой из запроса?
Запросом собираются данные по документам
«Посту плениеТоваров Услуг» PI выгружаются в таблицу значений «ТаблицаСсылок» (колонка «Ссылка»). Впоследствии к этой таблице значений будут добавляться еще строки. Как обеспечить возможность добавления в полученную таблицу значений в колонку «Ссылка» документов других видов («ОприходованиеТоваров»,
« ВозвратОтПокупателя» ) ?
При выгрузке данных из запроса в таблицу значений тип значения колонок определяется типом значений колонок результата запроса.
Поэтому одним из самых простых вариантов решения задачи может быть воздействие на запрос, а не на таблицу значений.
// Создать пустые ссылки.
ПустоеОприходованне = Документы. ОприходованиеТоваров. ПустаяСсылка)): Пустой Возврат = Докумен гы.ВозвратТоваровОтПокупателя.ПустаяСсылкаО;
// Выполнить запрос.
Запрос — Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
I Ссылка
/ИЗ
I Документ.ПоступлениеТоваровУслуг /ОБЪЕДИНИТЬ ВСЕ
ІВЫЬРАТЬ ПЕРВЫЕ 0 &ПустойДокументОприходованне (ОБЪЕДИНИТЬ ВСЕ
ІВЫЬРАТЬ ПЕРВЫЕ 0 &ПустойДокументВозвраг
I";
Запрос.УстановитьПарамезрСПустойДокументОприходование",
ПустоеОприхолование);
Запрос. УстановитьПараметрГ'ПустонДокументВозвра г". IІустой Возврат):
// Выгрузить в таблицу значений.
ТаблицаСсылок = Запрос.Выполнить().Выгрузить();
Создаем пустые ссылки на документы «ОприходованиеТоваров» и «ВозвратОтПокупателя».
Далее в запросе делаем объединение с записями, содержащими эти пустые ссылки. Причем в объединяемых запросах по пустым ссылкам применяем ПЕРВЫЕ 0 для того, чтобы впоследствии не удалять строки с пустыми ссылками из таблицы выгруженного результата запроса
После выполнения и выгрузки запроса в таблицу значений «ТаблицаСсылок» тип значения колонки «Ссылка» будет составным: «NULL, ДокументСсылка ЛоступлениеТ оваровУ слуг,
ДокументСсылка. ОприходованиеТ оваров, ДокументСсылка.ВозвратОтПокупателя».
То есть - то, что и требовалось.
Как самостоятельно заполнить дерево значений?
Для иллюстрации данной возможности создадим обработку, в которой определен реквизит «Дерево» (тип ДеревоЗначениЙ). В диалоге определено табличное поле, связанное через свойство данные с реквизитом «Дерево» (имя элемента управления «Дерево»).
Следующая процедура произведет запись данных в дерево значений.
|
Процедура ЗаполнениеДерева(Кнопка) |
|
Дерево.Колонки.ОчиститьО;
Дерево. Колонки. ДобавитьГ ИмяКолонки"); |
|
|
// Создать первую строку. Правильнее сказать создать элемент //коллекции. Он помешается в переменную «СтрокаВерхнегоУровня». |
|
СтрокаВерхнегоУровня = Дерево.Строкн.ДобавитьО; |
|
// В колонку «ИмяКолонки» записать значение «Старшая». СтрокаВерхнегоУровня.ИмяКолонки = "Старшая";
// Создать строку подчиненную «Старшей».
ПодчиненнаяСтрока =СтрокаВерхнегоУ ровня.Строки.Добавить(); ПодчнненнаяСтрока.ИмяКолонки = "Первая подчиненная";
Подчиненная ВторогоУ ровня = ПодчиненнаяСтрока.Строки.Добавить(): ПодчиненнаяВторогоУровня.ИмяКолонки = "Первая нижняя";
ПодчиненнаяВторогоУровня = ПодчнненнаяСтрока.Строки.Добавить(): ПодчиненнаяВторогоУровня.ИмяКолонки = "Вторая нижняя";
ПодчиненнаяСтрока = СтрокаВерхнегоУровня.Строки.ДобавитьО; ПодчнненнаяСтрока.ИмяКолонки = "Вторая подчиненная";
// Использование метода позволит увидеть результат работы // с деревом значений в табличном поле.
ЭлементыФормы. Дерево. СоздатьКолонкиО;
КонецПроцедуры
Следующая процедура показывает один из вариантов установки текущего значения в элементе управления, связанного с деревом (табличном поле).
Процедура ОткрытнеВеткиІ Кнопка)
// Сделать текущим именно элемент коллекции «Строки». РезультатПоиска = Дерево.Строки.НайтнСПервая нижняя".
"ИмяКолонки",
Истина);
Если РезультатПоиска о Неопределено Тогда ЭлементыФормы.Дерево.ТекущаяСтрока = РезультатПоиска; КонецЕсли;
КонецПроцедуры
Прикладные объекты
Справочники
© Как создать элемент (группу) справочника?
Создание нового элемента в неиерархическом справочнике можно выполнить при помощи следующего кода:
НовыйЭлемент = Справочники
.ДокументыУдостоверяюшиеЛичность
.СоздатьЭлементО;
НовыйЭлемент.Наименование = "военный билет";
// Установить другие реквизиты.
НовыйЭлемент.ЗапнсатьО;
Если справочник иерархический, то выполнение этого кода приведет к созданию нового элемента в корне справочника. Для того чтобы создать новый элемент в определенной группе иерархического справочника, необходимо также указать родителя создаваемого элемента:
НовыйЭлемент = Справочники. Банки.СоздатьЭлемент();
// Получить ссылку на группу, в которой будет находиться новый элемент. Родитель = Справочники.Банки.НайтиПоКодуС'ООООООООГ);
НовыйЭлемент.Наименование = "АКБ";
НовыйЭлемент.Код = "0000000 И";
НовыйЭлемент. Родитель = Родитель;
// Установить другие реквизиты.
НовыйЭлемент.ЗапнсатьО;
Если требуется создать новую группу в иерархическом справочнике, то для этого следует использовать метод менеджера справочника Создать Груп пу (). Если группа должна находиться внутри
определенной группы справочника, также следует указать и родителя создаваемой группы:
НоваяГруппа = Справочники. Номенклатура.СоздатьГ руппуО;
// Получить ссылку на группу, в которой должна находиться создаваемая группа. Родитель = Справочники.Номенклатура.НайтиПоНанменовашіюГОбуві,". Истина):
НоваяГруппа.Наимснование = "Модельная обувь":
НоваяГруппа.Родитель = Родитель;
// Установить другие реквизиты.
НоваяГруппа.Записать();
Следует обратить внимание на тот факт, что у реквизитов, в которые будет производиться запись значений в свойстве «Использование» должно стоять одно из перечисленных ниже значений:
• Для группы
• Для группы и элемента
Если для справочника установлен вид иерархии Иерархия элементов, то для создания новых элементов следует использовать метод СоздатьЭлемент() менеджера справочника, а иерархия создаваемых элементов будет определяться значением свойства Родитель объекта справочника:
// Создать новый элемент в корне справочника.
НовыйЭлемент = Спра вочннки. Подразделения.СоздатьЭлемент(); НовыйЭлемент.Наименованис = "IT отдел”;
НовыйЭлемент.ЗаписатьО:
// Получить ссылку на родителя добавляемых элементов.
Родитель = НовыйЭлемент.Ссылка;
// Создать дочерний элемент.
НовыйЭлемент = Справочники. Подразделения.СоздатьЭлемент(); НовыйЭлемент Наименование = "Группа разработки"; НовыйЭлемент.Родитель = Родитель;
НовыйЭлемент.ЗаписатьО:
Как найти элемент справочника?
Для поиска элемента справочника можно использовать несколько способов. По коду:
РезультатПоиска = Справочники.Номенклагура.НайтиПоКодуГ'ОООЗО”);
Если РезультатПоиска.ПустаяО Тогда
// Выполнить действия, предусмотренные в случае, когда элемент не найден. КонецЕсли;
При организации поиска по коду обращайте внимание на тип кода
справочника (Число или Строка).
По наименованию:
РезультатПоиска = Справочники .Номенклатура
.НаитиПоНаименованию("Кроссовки")
По реквизиту:
РезультатПоиска = Справочники .Номенклатура
.НайтиПоРеквизитуСАртикул", "К-120002”)
Во всех методах поиска есть параметры позволяющие искать в нужной группе, в рамках подчинения определенному элементу справочника владельца и ряд других параметров.
Как удалить элемент справочника?
Для корректного удаления элемента справочника необходимо убедиться в том, что другие данные не содержат ссылок на удаляемый элемент справочника.
Например, в переменной «СсылкаНаУдаляемыйЭлемент» содержится ссылка на удаляемый элемент справочника:
И Найти ссылки на удаляемый элемент.
МассивСсылок = Новый Массив;
МасснвСсылок.Добавить(СсылкаНаУдаляемыйЭлемент); НайдснныеСсылки = НайтиПоСсылкам(МассивСсылок);
Если НайдснныеСсылки.КоличествоО > 0 Тогда СообщитьС'Нельэя удалять элемент, на него имеются ссылки");
Иначе
УдаляемыйЭлемент = СсылкаНаУдаляемыйЭлемент.ПолучитьОбъект(): У даляемыйЭлемент.Удалить!);
КонецЕсли:
Для пометки элемента справочника на удаление можно использовать метод УстановитьПометкуУдаления() объекта справочника:
УдаіясмыйЭлемент.УстановнтьПометкуУдаления! Истина);
Использование этого метода позволяет установить или снять пометку на удаление элемента справочника, причем будут инициированы события Перед записью и При записи объекта справочника, поскольку выполняется сохранение измененного свойства ПометкаУдаления объекта справочника.
Как перебрать элементы справочника?
Для того чтобы перебрать элементы справочника, необходимо сформировать выборку элементов с нужными параметрами и затем обойти ее в цикле.
Например, для перебора всех элементов справочника «Номенклатура» в иерархическом порядке, можно использовать следующий код:
Выборка = Справочники.Номенклатура.ВыбратьИерархически():
Пока Выборка.СлсдуюшийО Цикл Наименование = Выборка.Нанменованне;
// Обращение к другим данным справочника.
КонсцЦикла:
Аналогичного результата можно добиться, используя запрос:
Запрос = Новый Запросе ІВЫБРАГЬ I Ссылка,
I Наименование |ИЗ
I Справочник.Номенклатура ІАВТОУПОРЯДОЧ И ВАНИ Е");
Результат = Запрос.ВыполнитьО.Выбрать():
Пока Результат.СледующийО Цикл Наименование = Результат.Наименование;
КонецЦикла;
Благодаря использованию запроса можно формировать выборку элементов справочника более «гибко», поскольку запрос позволяет задать произвольные условия на выбираемые данные.
® Как выбрать все элементы из определенной группы?
Организуем выборку элементов справочника из группы, ссылка на которую определена в переменной «ПолеВводаРодитель»:
Выборка = Справочники.Номенклатура.Выбрать (ПолеВводаРодитель):
Пока Выборка.СледующийО Цикл Наименование = Выборка.Наименование;
КонецЦикла;
В результате работы этого кода будут получены все дочерние элементы выбранного элемента справочника. Аналогичное действие, выполняемое с помощью запроса, будет выглядеть следующим образом:
Запрос = Новый ЗапросГ ІВЫЬРАТЬ I Ссылка.
I Наименование |ИЗ
I Справочник.Номенклатура
|ГДЕ
I Родитель = &Роднтель ІАВТОУПОРЯДОЧИВАНИЕ");
Запрос.УстановитьПараметрГРодитель”, ПолеВводаРодитель): Результат = Запрос.Выполнить().Выбрать():
Пока Результат.СледуюшинО Цикл Наименование = Результат.Наименование;
КонецЦикла:
Если необходимо получить не только дочерние элементы, но и все элементы, находящиеся в иерархии выбранного элемента, следует, при использовании объектной техники, выполнять метод ВыбратъИерархически() менеджера справочника:
Выборка=Справочникн.Номенклатура.ВыбратьИерармічески(ПолеВводаРодитель); Пока Выборка.СледующийО Цикл Наименование = Выборка.Наименование;
КонецЦикла;
а при использовании запроса применять условие В ИЕРАРХИИ:
Запрос = Новый ЗапросС ІВЫБРАТЬ I Ссылка.
I Наименование |ИЗ
I Справочник.Номенклатура ІСДЕ
I Родитель В ИЕРАРХИИ(&Родитель) ІАВТОУПОРЯДОЧИВАНИЕ");
Запрос.УстановитьПараметрГРодитель", ПолеВводаРодитель); Результат = Запрос. Выполнит ь().Выбрать();
Пока Результат.СледуюшийО Цикл Наименование = Результат.Наименование;
КонецЦикла;
® Как перебрать элементы подчиненного справочника с помощью запроса?
Справочник «КонтактныеЛица» подчинен справочнику «Контрагенты».
Требуется перебрать всех контактных лиц определенного контрагента. Ссылка на данного контрагента находится в переменной «Контрагент».
Процедура ПсреборПодчнненых'Элементов( Контрагент)
Запрос = Новый Запрос:
Запрос.Текст = "ВЫБРАТЬ I КонтактныеЛица.Ссылка |ИЗ
I Справочник.КонтактныеЛица КАК КонтактныеЛица
I
|ГДЕ
I КонтактныеЛнца.Владелец = & Владелец";
Запрос.УстановитьПараметрС'Владелец", Контрагент);
Результат = Запрос.ВыполнитьО:
Выборка = Результат.Выбрать();
Пока Выборка.СледующінК) Цикл ОчереднойПодчиненый = Выборка.Ссылка; КонецЦикла;
КонецПроцедуры
Делаем запрос по таблице справочника «Контактные лица» с отбором по полю «Владелец». В качестве владельца передаем ссылку на элемент справочника «Контрагенты».
® Как перебрать элементы подчиненного справочника с помощью выборки справочника?
Справочник «КонтактныеЛица» подчинен справочнику «Контрагенты».
Требуется перебрать всех контактных лиц определенного контрагента. Ссылка на данного контрагента находится в переменной «Контрагент».
Процедура ПереборПодчинемыхЭлементов(Контрагент)
// Получить выборку по указанному контрагенту.
Выборка = Справочники.КонтактныеЛица.Выбрать(. Контрагент)
Пока Выборка.СледующийО Цикл ОчереднойПодчиненый = Выборка.Ссылка;
КонецЦикла;
КонецПроцедуры_
ф Как открыть форму списка (элемента) справочника?
Для того чтобы открыть форму списка справочника, можно воспользоваться методом ПолучитьФормуСписка() менеджера справочника:
Форма = Справочники. Номенклатура.ПолучнтьФормуСпискаО; Форма.ОткрытЫ);
Для того чтобы открыть произвольную форму справочника, можно использовать метод ПолучитьФормуО менеджера справочника:
Форма = Справочники
. X ран ил и щеДопол н ител ьнон И нформаци и .ПолучитьФормуС'ФормаСпискаФайловИИзображенин”); Форма.ОткрытьО;
Однако следует помнить, что если методом ПолучитьФорму() выполняется получение формы элемента или группы справочника, то будет получена форма нового элемента (группы).
Для того чтобы открыть форму существующего элемента или группы справочника, следует использовать метод ПолучитьФорму() ссылки или объекта справочника:
Элемент = Справочники. Номенклатура. НайтиПоКолуГОООЗО”); Форма = Элемент.ПолучитьФормуО;
Форма. Оікрыіьр;_
® Как добавить запись в табличную часть элемента справочника?
Имеется ссылка на элемент справочника «Контрагенты». Как добавить запись в табличную часть «ВидыДеятельности» этого элемента? Модифицировать можно только объект справочника.
Поэтому так:
ЭлементОбъект = СсылкаКонтрагент.ПолучнтьОбъектО; НоваяСтрока = ЭлементОбъект. ВидыДеятельности. Добавить():
// Заполнить реквизиты.
НоваяСтрока.ВилДеятельности = ПолеВводаВидДеятельности: ЭлементОбъект.ЗаписатьО:
Получаем объект справочника от ссылки на элемент.
Добавляем новую строку к табличной части полученного объекта. Заполняем реквизиты табличной части в данной строке.
Записываем измененный элемент справочника.
Как удалить строки из табличной части справочника?
Для того чтобы полностью очистить табличную часть элемента справочника, можно воспользоваться методом ОЧИСГИТЬ() табличной части справочника:
Элементе правочника = С правочнн кн. Контрагенты. НантиПоКоду(" Ю0006''); ОбъектСправочника = ЭлементСправочиика.ПолучитьОбъект(); ОбъектСправочника.ВидыДсятельности.ОчнститьО; ОбъектСправочника.ЗанисатьО;
Если требуется выборочное удаление строк табличной части (например, в зависимости от значения их реквизитов), можно сначала отобрать строки, удовлетворяющие условию, а затем удалить каждую из них методом Удалить() табличной части справочника. В следующем примере подразумевается, что переменная «ВыбранныйЭлемент» содержит ссылку на обрабатываемый элемент справочника, а переменная «ВыбранныйВидДеятельности» содержит ссылку на вид деятельности, который не должен присутствовать у обрабатываемого элемента:
|
ОбъектС’правом ника = ВыбранныйЭлемент. ПолучитьОбъс |
кт(): |
|
// Создать структуру для отбора удаляемых строк. |
|
|
СтруктураОтбора = Новый СтруктураС'ВидДеятельности' |
|
ВыбранныйВидДеятельности);
// Получить массив удаляемых строк.
ПодходяшиеСтроки = ОбъсктСнравочника .ВидыДеятельности .НайтиСтроки(СтруктураОтбора); |
|
II Удалить строки. |
|
|
Для Каждого ОчерсднаяСтрока Из ПодходящиеСгроки Ці |
пел |
ОбъектСправочника.ВидыДеятелыюсти.Удалить(Очсрс
КонецЦикла;
ОбъектСправочника. Записать)): |
інаяСтрока); |
ф Как перебрать строки табличной части справочника?
Табличная часть справочника представляет собой коллекцию строк, которую можно перебрать в цикле. Реквизиты табличной части будут доступны как свойства строки табличной части.
Например, перебор строк табличной части «ВидыДеятельности» справочника «Контрагенты» может быть выполнен следующим образом:
ЭлсмснтСправочннка = Справочники. Контрагенты. НайтиІ ІоКоду("КХХХ)6");
Для Каждого ТекущаяСтрока Из ЭлементСправочника.ВндыДеятельности Цикл Сообщить(ТекушаяСтрока.ВидДеятельностн);
КонецЦикла;
® Как создать элемент в нужной группе?
Необходимо создать элемент справочника номенклатура, так чтобы при этом он попал в нужную группу. Если группы с указанным кодом нет, то тогда такая группа должна быть создана.
КодГруппы = "ЗЗОІОО";
ПоискПоПолномуКоду = Ложь; // значение по умолчанию Группа = Справочники.Номенклатура
.НайтиПоКоду(КодГруппы. ПоискПоПолномуКоду)
Если Группа.ПустаяО Тогда Группа = Справочники.Номенклатура.СоздатьГруппуО:
Группа.Код = КодГруппы;
Г рунпа.Наименование = "Загруженные";
Г руппа.3аписать();
ИначеЕсли Не Группа.ЭтоГруппа Тогда СообіцитьС'Найден элемент справочника с указанным кодом!");
// Предусмотреть прерывание алгоритма.
КонсцЕсли;
Спр = Справочники.Номенклатура.СоздатьЭлемент(); Сир.Наименование = "Программно созданный":
// Реквизиты заполняются в соответствии с задачей.
Спр.Родитель = Группа.Ссылка;
Спр.ЗаписатьО;
Можно использовать предопределенную группу, в этом случае вместо поиска и создания новой группы можно использовать строку:
Группа = Справочники.Номенклатура.Загруженные:
Обратите внимание на тот факт, что механизм работает, только если в справочнике установлен вид иерархии «Иерархия групп и элементов». В противном случае код будет выглядеть следующим образом:
КодЭлемента = "330100";
ПомскПоПолномуКоду = Ложь; //Значение по умолчанию Родитель = Справочники.Номенклатура
.НайтиГ1оКоду(КодЭлемента, ПонскІІоПолномуКоду);
Если Родитель.ПустаяО Тогда Родитель = Справочники. Номенклатура.СоздатьЭлемент():
Родитель.Код = КодЭлемента:
Родитель.Наименованне = "Загруженные”;
Родитель. За писать/);
КонецЕсли;
Спр = Справочники.Номенклатура.СоздатьЭлемент():
Спр.Наименование = 'Программно созданный";
// Реквизиты заполняются в соотвествии с задачей.
Спр.Родитель = РоднтельСсылка: Спр.ЗаписатьО;
Если вид иерархии справочника «Иерархия элементов», то понятие группы в нем отсутствует.
Как узнать, есть ли у текущего элемента подчиненные?
Пусть ссылка на текущий элемент справочника содержится в переменной «Владелец». Необходимо узнать, есть ли в справочнике «Единицы измерения» элементы, подчиненные текущему элементу.
Если использовать объектную модель доступа:

Фактически получаем выборку всех подчиненных элементов и если в выборке есть хоть одна позиция, считаем, что подчиненные элементы существуют. Именно этот факт и говорит о неэффективности использования данного варианта (выбираемые данные мы не используем, а получаемый блок данных может быть большим).
Лучше всего подобную проверку можно выполнить, используя возможности запросов:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ I
I ЕдиницыИзмереішя.Ссылка
|ИЗ
I Справочник.ЕдиницыИзмерения КАК Единицы Измерения |ГДЕ
I Единицы Измерения.Владелец = &Владелец"';
Запрос.УстановитьПараметрС'Владелец". Владелец);
Если НЕ Запрос.Выполнить) ).Пустой() Тогда // Есть подчиненные элементы!
КонсцЕсли
Так как не предполагается, что нам понадобятся данные о подчиненном элементе, выборку результата запроса в переменной не сохраняем.
Как узнать количество подчиненных элементов у выбранного элемента справочника?
Необходимо определить количество элементов в справочнике «ЕдиницыИзмерения» подчиненных элементу справочника, ссылка на который находится в переменной «Владелец». С помощью объектной модели:
Выборка — Справочники.Единицы Измерения.Выбрать) , Владелец): КоличествоЭлементов = О;
Пока Выборка.СледующиГц) Цикл КоличествоЭлементов = КоличествоЭлементов + I;
КонецЦикла;
Данное решение в общем случае является не эффективным. Связано это с тем, что выборка фактически получает все данные о подчиненных элементах справочника, а в рамках данной задачи нужно только количество элементов.
Если решать задачу с помощью запроса, то решение выглядит следующим образом:
Запрос = Новый Запрос;
Зал рос. Текст = "ВЫБРАТЬ I КОЛИЧЕСТВО»*) КАК Количествозаписей |ИЗ
I Справочник.ЕдиницыИзмереиия КАК Единицы Измерения |ГДЕ
I ЕдиницыИзмерения.Владелец = &Владелец";
Запрос.УстановитьПараметрС'Владелец”. Владелец); Выборка = Запрос.Выполнить»).Выбрать));
Если Выборка.СледуюшийО Тогда КоличествоЗаписей = Выборка.КоличествоЗаписей: КонецЕсли;
В результате в переменной «КоличествоЗаписей» будет находиться нужная нам величина.
Как узнать количество подчиненных элементов у выбранного элемента справочника, если количество подчиненных справочников больше чем один?
Если у справочника есть несколько подчиненных справочников, то запрос может выглядеть следующим образом:
ВЫБРАТЬ
СУММА(КолнчествоПодчиненных) КАК КоличествоПодчиненныхЭлементов ИЗ
(ВЫБРАТЬ
КОЛИЧЕСТВО^) КАК КоличествоПодчинеішых ИЗ
Справочник.ЕдиницыИтмерения КАК ЕдиницыИтмерсння ГДЕ
ЕдиницыИтмерения. Владелец = & Владелец
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
КОЛИЧЕСТВО)*)
ИЗ
Справочннк.СерииНоменклатуры КАК СерииНоменклатуры ГДЕ
СерииНоменклатуры.Владелец = & Владелец ) КАК ВложенныйЗапрос
Данный запрос позволяет получить количество записей в двух подчиненных справочниках. В качестве источника данных в основном запросе используется подзапрос («ВложенныйЗапрос»). Сам подзапрос состоит из двух запросов (происходит их объединение). Каждый из объединяемых запросов получает данные о количестве записей в одном из подчиненных справочников.
В выборке результата запроса (в случае если у элемента справочника, ссылка на который находится в переменной «Владелец», есть подчиненные элементы) будет одна строка, в поле «КоличествоПодчиненныхЭлементов» которой содержится количество подчиненных элементов.
Как получить всех родителей выбранного элемента справочника?
В переменной «СсылкаНаЭлемент» находится ссылка на элемент справочника. Необходимо получить всех родителей данного элемента
МассивРоднтелей = Новый Массив; Родитель = СсылкаНаЭлемсн і .Родитель;
Пока Не Родитель.Г1устая() Цикл МассивРодителей.Добавить(Родитель): Родитель = Родитель.Родитсль: КонецЦикла:
Перебрать всех родителей можно используя строки кода:
Для Каждого ТекущийРодитель Из МасснвРодитслей Цикл // Работа с текущим родителем.
КонецЦикла:
Данную задачу можно решить и с помощью запроса, однако следует учитывать, что в языке запросов не предусмотрено специальных средств для получения всех родителей элемента. Для выполнения задачи можно воспользоваться, например, иерархическими итогами, текст запроса будет выглядеть следующим образом:

Результат запроса будет содержать одну «лишнюю» запись, которую легко «отсеять» проверкой свойства «ЭтоГруппа».
Однако получение иерархических итогов оптимизировано для построения итогов большого количества записей, и не вполне эффективно для получения родителей одного элемента. Для более эффективного получения всех родительских записей элемента, рекомендуется перебирать в цикле его родителей небольшими порциями, например, так:
ТекущийЭлементНомснклатуры = ЭлементНомснклатура;
Запрос = Новый ЗапросОВЫБРАТЬ I Номенклатура.Родитель,
I Номенклатура.Родитель.Родитель.
I Номен клатура. Родитель. Родител ь. Родител ь,
I Номенклатура.Родитель.Роднтель.Родитель.Роди гель.
I Номенклатура.Родитель.Роднтсль.Родитель.Роднтель. Родитель |ИЗ
I Справочник.Номенклатура КАК Номенклатура |ГДЕ
I Номенклатура.Ссылка = &ТекушийЭлементНомснклатуры";
Пока Истина Цикл
Запрос.УстановитьПарачетр("ТекуіцийЭлеменгНоменклатуры'\ ТекуіцийЭлемеіп Номенклатуры); Ретультат = Запрос.Выполнить!);
Если Результат.ПустойО Тогда Прервать;
КонецЕсли;
Выборка = Ретультат. Выбрать!);
Выборка.СледующийО;
Для НомерКолонки = 0 По Рстулмат.Колонки.Количоство!) - I Цикл ТекущийЭлемент I Іомснклаі уры = Выборка) I ІомерКолонки);
Если ТекушнйЭлементНоменклатуры = Справочники
.Номенклатура .ПустаяСсылкаО Тогда
Прервать:
Иначе
Сообшить(ТекушийЭлсментНомснклатуры);
КонецЕсли;
КонецЦикла;
Если ТекущийЭлементНоменклагуры = Справочники
.Номенклатура ПустаяСсылкаО Тогда
Прервать:
КонецЕсли;
КонецЦикла;
В данном примере в окно служебных сообщений выводятся все родители для ссылки, записанной в переменную «ЭлементНоменклатура». В цикле выбирается по 5 родителей ссылки.
Если число уровней в справочнике ограничено и невелико, то возможно получение всех родителей одним запросом без цикла.
Как получить запросом «полный» код элементов справочника, если тип кода -Строка?
Понятие «Полный код» соответствует объектной модели системы. Это свойство объектов «СправочникСсылка» и «СправочникОбъект», содержащее указание кодов элемента и всех родителей его иерархии. Представляет собой строку, в которой указаны коды всех вышестоящих элементов иерархии, начиная с самого верхнего уровня и разделяемые символом «/» заканчивая кодом самого элемента.
В табличной модели хранения информации никакого поля «ПолныйКод» для таблиц справочника не существует.
Однако можно говорить о значении поля «Родитель» каждой из записей таблиц справочников и о значении поля «Код».
Поэтому запрос по трехуровневому справочнику «Контрагенты» будет выглядеть следующим образом:
ВЫБРАТЬ
Контрагенты .Ссыл ка,
ВЫБОР
КОГДА (Контрагенты.Родитель.Код ЕСТЬ NULL ) ТОГДА Контрагенты.Код КОГДА (Контрагенты.Роднтель.Родитель.Код ЕСТЬ NULL )
ТОГДА Контрагенты.Родитель.Код + "/" + Контрагенты.Код ИНАЧЕ Контрагенты.Родитель.Родитель.Код + 7“
+ Контрагенты.Родитель.Код + "Г + Контрагенты.Код КОНЕЦ КАК ПолныйКод ИЗ
Справочник.Контрагенты КАК Контрагенты
Источником является таблица справочника. Из нее выбираем поле «Ссылка» и вычисляемое поле «ПолныйКод».
Вычисление полного кода производим путем сборки его из значений кодов самого элемента и кодов всех вышестоящих родителей. Для этого для каждой записи сначала определяем ее уровень.
Уровень определяем следующим образом: для записей корневого уровня поле «Родитель» содержит пустую ссылку на элемент справочника, поэтому значение поля «Код» этого «Родителя» будет NULL. Если это условие выполнилось - значит, элемент находится на корневом уровне, и в качестве полного кода достаточно указать код.
Если условие не выполнилось - проверяем аналогичным способом элемент на принадлежность к первому уровню. В случае выполнения условия — выводим уже код родителя и код самого элемента через «/».
Таким же образом можно построить «сборку» поля «ПолныйКод» для случаев 4-х, 5-ти и т.д. уровневых справочников.
В отношении возможных возражений о «неуниверсальности» подобного подхода: хотя, в общем случае, количество уровней справочника может быть не ограничено, сложно представить себе реальную практику использования справочника более чем с 10 уровнями вложенности из-за явного неудобства работы пользователя с таким «глубоким» справочником.
Как получить все элементы справочника, содержащие в наименовании определенную подстроку, со всей иерархией, в которую они входят?
Допустим, речь идет о справочнике «Контрагенты».
Лучше всего с данной задачей справится запрос со следующим текстом:
Запрос = Новый ЗапросС'ВЫБРАТЬ I Контрагенты.Ссылка КАК Ссылка |ИЗ
I Справочник.Контрагенты КАК Контрагенты |ГДЕ
I (Контрагенты.Наименование ПОДОБНО &ЧастьНаимснования) I И
I (НЕ Контрагенты.ЭтоІ руппа)
I
Іитоги по
I Ссылка ТОЛЬКО ИЕРАРХИЯ");
Запрос. УстановитьПараметрС'ЧастьНаименования",
+ ПолеВводаПодстрока +
Источником запроса является таблица справочника. Делаем отбор по наименованиям, в составе которых присутствует значение параметра «ЧастьНаименования». Условие отбора обеспечивается посредством оператора проверки строки на подобие шаблону. В шаблоне служебными символами «%» обозначается, что перед и после части строки, считанной из «ПолеВводаПодстрока», может встречаться произвольное количество других символов.
Как найти все элементы справочника, в которых не заполнен строковый реквизит?
Получить желаемое можно таким запросом:

ВЫБРАТЬ
ФизнческиеЛица.Ссылка
ИЗ
Справочник.ФизическисЛица КАК Фи жческиеЛица ГДЕ
(ФизическиеЛица.ИНН =
Проверка пустой строки выполняется за счет операции сравнения «=». В данном случае будут отобраны и элементы, в которых пользователь ничего не вводил и даже те, в которые он ввел только пробел (или пробелы). Но на некоторые реквизиты при работе с формой накладывают маску. В таких случаях случайный ввод хотя бы одного пробела уже не позволяет данному реквизиту быть пустым. Его значение будет содержать маску с пробелами.
Для того, чтобы «защитить пользователя от самого себя» в подобных случаях запрос лучше немножко изменить. Например, для реквизита с маской «999-999-999 99» запрос будет выглядеть таким образом:
ВЫБРАТЬ
ФизнческиеЛица.Ссылка
ИЗ
Справочник.ФизическнсЛица КАК ФизичеекиеЛица ГДЕ
(ФнзическиеЛица.СтраховойНомерПФР = "") ИЛИ (ФизическиеЛица.СтраховонНомерПФР = ” - -")
Количество пробелов перед и между символами «-» должно соответствовать маске.
Как перенести все элементы справочника «Контрагенты» из одной группы в другую?
Для этого необходимо перезаполнить значением нового родителя реквизит «Родитель» у элементов, непосредственно являющихся «потомками» исходного родителя.
Итак, пусть переменная «СтарыйРодитель» содержит старого, а «НовыйРодитель» - нового родителя.
Получение элементов справочника, которым нужно поменять родителя, производим следующим образом:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ I Контрагенты.Ссылка |НЗ
I Справочник.Контрагенты КАК Контрагенты |ГДЕ
I Контрагенты.Родитель = &СтарыйРодитель";
Запрос.УстановитьПараметрІ"СтарыйРодитель". СтарыйРодитель) Результат = Запрос. Выполнить));
Источником для запроса является таблица справочника «Контрагенты». Делаем отбор непосредственно по полю «Родитель» и получаем таблицу ссылок на нужные нам элементы справочника.
Далее:
Выборка = Результат.ВыбратьО;
Пока Выборка.СледующийО Цикл Контрагент = Выборка.Ссылка. Получит ьОбъектО; Контрагент.Родитель = НовыйРодитель; Контрагент. Записать));
КонецЦикла:
В цикле обработки результата запроса производим получение объекта по ссылке. Для каждого полученного объекта производим запись нового родителя в реквизит «Родитель» и непосредственную запись объекта с измененными данными.
Как организовать программный выбор элемента справочника?
Требуется из одной формы (например, формы документа) открыть для выбора элемента форму справочника. После того, как значение будет выбрано в форме справочника, его необходимо получить для дальнейшей обработки в форме документа.
// Получить форму выбора справочника как подчиненную // форме документа
ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора( . ЭтаФорча):
// Открыть полученную форму ФормаВыбора Открытій):
Для получения выбранного значения используется обработчик события Обработка выбора формы владельца (в нашем случае формы документа).
Процедура ОбработкаВыбора(ЗначениеВыбора, Источник)
ПолученноеЗначение = ЗначениеВыбора:
// Дальнейшая обработка значения.
КонецПроцедуры
Вместо метода Открыть() объекта Форма Выбора в ряде случаев можно использовать метод ОткрытьМодально(). В этом случае окно откроется в модальном режиме и пока данная форма не будет закрыта, работать с другими формами, объектами в рамках данного клиентского приложения будет нельзя. Выполнение процедуры также будет остановлено на данном месте и продолжрггся после закрытия формы.
ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбораІ . ЭтаФорма): Выбрано = ФормаВыбора.ОткрытьМодальноО;
Аналогичным образом можно организовать выбор для поля ввода. Для этого, в обработчике события Начало выбора поля ввода следует отключить стандартную обработку и получить нужную форму выбора как подчиненную данному полю ввода. Например:
Процедура ПолеВводаІ ІачалоВыбора(Элемент, СтандартнаяОбработка)
// Запретить стандартную обработку.
СтандартнаяОбработка = Ложь;
// Получить форму выбора справочника как подчиненную полю ввода ФормаВыбора = Справочники .Номенклатура
.ПолучитьФормуВыбора(, Элемент);
// Открыть полученную форму ФормаВыбора.Открыть();
КонецПроцедуры
Если есть необходимость в использовании собственного алгоритма обработки выбранного значения, его следует размещать в обработчике события Обработка выбора поля ввода:
Процедура ПолеВводаОбработкаВыбораІ Элемент,
ВыбранноеЗначенне,
СтандартнаяОбработка)
//Отключить стандартную обработку (при необходимости). СтандартнаяОбработка = Ложь;
ПолученносЗначснне = ВыбранноеЗначенне;
// Дальнейшая обработка значения.
КонецПроцедуры
Как сохранить фотографию сотрудника в справочнике «Сотрудники»?
Необходимо создать реквизит справочника «Фотография» и определить у него тип ХранилИЩеЗначения. Далее в форме элемента определить кнопку (либо использовать кнопку командной панели), при нажатии на которую, будет выполняться следующий обработчик события:
Процедура ЗагрузитьФотографию(Элемент)
Режим = РсжимДиалогаВыбораФайла.Открытие;
ДиалогОткрытияФайла = Новый ДиалогВыбораФайлаі Режим); ДиалогОткрытияФайла.ПолноеИмяФайла =
Фильтр = "Текст (*,*)|*.*”;
ДиалогОткрытияФайла.Фильтр = Фильтр; ДиалогОткрытияФайла.МножественныйВыбор = Ложь; ДиалотОгкрытняФайла.Заголовок = "Выберите картинк)”;
Если ДиалогОткры гияФанла.ВыбратьО Тогда ВыбранмаяКартинка =
Новый Картннка(ДиалогОткрытияФанла.ПолноеИмяФанла) 'Элемені Хранилища = Новый Хранил ищсЗначсннЖ ВыпраннаяКартинка): Фотография = ЭлементХранилища;
КонецЕсли;
КонецП роцедуры
В данной процедуре первоначально создается объект ДиалогВыбораФаЙла. Метод Выбрать() открывает данный диалог и в случае выбора возвращает значение Истина.
В приведенном примере в объект ХранилищеЗначения помещается объект Картинка. Это удобно в том случае, если предполагается, что после извлечения, картинка будет отображаться в элементе управления ПолеКартинки диалога какой-либо формы. .В противном случае в реквизит можно помещать не значение, имеющее тип Картинка, а значение с типом ДвоичныеДанные.
ВыбФайл = Новый ДвоичныеДанные(ДиалоіОткрытияФапла.ГІолноеИмяФайла); элХранилища = Новый ХранилищеЗначения(ВыбФайл);
Фотография = элХранилища;
Можно сказать, что в реквизит справочника записывается объект ХранилищеЗначения, в который помещен указанный файл.
Замечание: при разработке структуры данных прикладного решения следует внимательно относиться к использованию полей, имеющих тип ХранилищеЗначения. В качестве общей рекомендации можно посоветовать создавать структуры данных, которые обеспечат отдельное от основной информации хранение таких полей. Например, фотографию сотрудника лучше хранить не в реквизите самого справочника «Сотрудники», а в отдельном справочнике или регистре сведений. Объекты системы (в данном случае элементы справочника «Сотрудники») считываются системой всегда целиком, поэтому хранение больших объемов информации непосредственно в полях объектов может существенно замедлить работу системы.
Документы
© Как создать новый документ?
Если создание нового документа должно пройти без участия пользователя, можно сделать так:
НовыйДокумемт = Документы. ПриходныйКассовыйОрдер.СоздатьДокумснтО НовыйДокумент.Дата = ТекущаяДатаО:
Переменная «НовыйДокумент» в таком случае имеет тип значения ДокументОбъект - мы сразу получаем объект нового документа. А значит, обращаясь к ней, впоследствии можно заполнить реквизиты документа и записать его.
Если нам нужно не просто создать новый документ, но и дать возможность пользователю поучаствовать в процессе его заполнения и записи, то лучше сделать так:
ФормаНовогоПКО = Документы
.ПриходныйКассовыйОрдер .ПолучитьФормуНовогоДокуменгаО; ФормаНовогоПКО.Открыть():
В данном случае после создания документа мы открываем основную форму этого документа для редактирования его пользователем.
Как найти документ?
Например, нужно найти в 2005 году документ
«РеализацияТоваровУслуг» по номеру «НомерДок» (периодичность нумерации - «в пределах года»). Тогда так:
ИскомыйДокумент = Документы
.РеализацияТоваровУслуг НайтиПоНомеру(НомерДок, Дата(2005, I, 1));
Если НЕ ИскомыйДокумент.ПустаяО Тогда
// Выполнить действия в случае обнаружения такого документа.
КонецЕсли: ]
Второй параметр метода НаЙТИПоНомеру() используется в случаях периодических нумерациый документов и может содержать любую дату из того периода, в рамках которого нужно искать документ.
Если же поиск нужно выполнять по реквизиту, то можно, конечно, использовать объектную модель работы с данными - метод НаЙТиПоРеквизиту() менеджера документа. Однако в результате будет получен только один из документов с искомым значением реквизита.
Гораздо удобнее для выполнения операций поиска использовать запросы. Например, с таким текстом:
ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка
ИЗ
Документ. РеализацияТоваровУслуг КАК РеализацияТоваровУслуг ГДЕ
РеализацняТоваровУслуг.Контрагент = &Контрагент И (РеализацияТоваровУслуг.Номср < 100 ИЛИ
РеализацияТоваровУслуг.Дата < ДАТАВРЕМЖ2005. 1, I))
И РеалнзацияТоваровУслуг.Товары.Номенклатура _В ИЕРАРХИИ(&Номенклатура)
Такой запрос позволяет получить все документы «РеализацияТоваровУслуг» по указанному контрагенту, закупавшему товары из указанной номенклатурной группы ранее 1 января 2005 года или позже, но с номерами документа менее «100».
Как открыть форму документа?
В переменной «ИскомыйДокумент» содержится ссылка на документ. Если требуется открыть основную форму этого документа, это можно выполнить так:
Форма = ИскомыйДокумснт.ПолучитьФорму(); Форма. Открыть();
Ф Как изменить значение реквизита и записать документ?
Например, переменная «СсылкаНаДокумент» содержит ссылку на тот документ, который необходимо изменить. Сначала по ссылке нужно получить объект ДокументОбъект. Потом можно установить значение нужного реквизита, и записать измененный документ.
ДокОбъект = С'сылкаНаДокумент.ПолучитьОбъект(); ДокОбъект.Ответственнын = г л Те ку щи й П oj і ыовател ь:
ДокОбъект.Записать»);
Обращайте внимание, требуется ли обеспечить проведение измененного документа. В нашем примере документ был записан без проведения.
Если необходимо при этом провести документ, то:
ДокОбъект.Записать» РежимЗаписнДокумента. Проведение);
Первым параметром метода передается значение Проведение системного перечисления РежимЗаписиДокумента, а вторым параметром можно указать режим проведения
(оперативный/неоперативный, так же выбирается из соответствующего системного перечисления).
Если же наоборот, нужно отменить проведение документа, то:
ДокОбъскг.Записать» РежимЗаписиДокумента. ОтмснаПро ведения);
Во всех перечисленных случаях система передаст управление соответствующим ситуации обработчикам событий (Перед записью, При записи, Обработка проведения, Обработка удаления проведения).
Замечание: В языке системы нет специальной команды для инициализации выполнения проведения или отмены проведения документа. Все выполняется при соответствующем способе записи документа.
® Как добавить строку в табличную часть документа, имея ссылку на документ?
Допустим переменная «Док» содержит ссылку на документ. Имя табличной части этого документа - «Товары». Тогда:
ОбъектДок = Док.ПолучитьОбъектО: НоваяСтрока = ОбъектДок. Товары. Добавить!);
// Заполнить значения реквизитов. НоваяСтрока.Количество = 10; НоваяСтрока.Цена = 55;
// Записать документ.
ОбъектДок.ЗаписатьО;
Сначала получаем объект документа. Потом добавляем новую строку в табличную часть «Товары» документа. Результат метода Добавить() и есть новая строка. Теперь можно заполнить значения ее реквизитов.
В конце нужно не забыть записать документ.
ф Как удалить строки из табличной части документа?
В переменной «Документ» содержится ссылка на документ. Если требуется модифицировать этот документ - удалить строки из табличной части «Товары» этого документа, - это можно выполнить так:
ОбъектДокумента = Документ.ПолучитьОбъекгО; ОбъектДокумента.Товары.Очистить();_
По окончании всех модификаций, если это требуется, не забудьте записать документ.
ОбъектДокумента. ЗаписатьО;
В данном случае документ записан без проведения. Подробнее о записи документа с проведением смотри вопрос «Как провести документ?» на странице 109.
Какперебрать строки документа?
У документа может быть несколько табличных частей.
Перебор строк каждой табличной части проще производить в цикле перебора элементов коллекции или при помощи «цикла-счетчика».
Например, чтобы перебрать строки табличной части «Товары» документа «Документ», можно сделать так:
Для Каждого ТекущаяСтрока Из Документ.Товары Цикл //Действия со строкой табличной части.
КонецЦикла;
|
А можно так: |
 |
ф Как выгрузить табличную часть документа?
Чтобы выгрузить табличную часть «Товары» документа «Документ» в таблицу значений, можно сделать так:
ТаблицаТоваровДокумента = Докумснт.Товары.Выг руіні ь():
В результате система создаст таблицу значений с колонками, соответствующими колонкам табличной части и заполнит ее данными.
® Как посчитать итог в табличной части документа?
Итог по колонке «Сумма» табличной части «Товары» документа «Документ» можно посчитать следующим образом:
ВсегоПоКолонкеСумма = Документ.Товары.Итог( "Сумма"):
Как провести документ?

Первым параметром метода Записать() следует указание режима записи документа. Тип его значения задается системным перечислением РежимЗаписиДокумента, и может принимать следующие значения:
• Запись;
• ОтменаПроведения;
• Проведение
В нашем случае - это Проведение. Теперь при выполнении этой команды управление будет передано в обработчик события Обработка проведения записываемого документа.
Обратите внимание - нет отдельной команды на проведение, есть только запись документа, с проведением или без.
Какперебратьдокументы?
Для перебора всех документов, например «РеализацияТоваровУслуг», можно использовать выборку.
Выберем, например, документы за текущий год.
ВыборкаДокументов = Документы. Расходная. Выбраі ьІНачалоГода(ТекущаяДата()).
КонецГ ода(ТекущаяДата()));
Пока ВыборкаДокументов.СледуюшийО Цикл
// Действия с документом - элементом выборки.
// его значение содержится в переменной ВыборкаДокументов
КонецЦикла
В теле цикла можно работать с каждым отдельным элементом выборки.
Однако, в случаях, когда требуется перебрать документы, соответствующие ряду условий - гораздо удобнее получать нужные документы при помощи запроса:
Запрос = Новый Запрос;
Запрос.Текст ="
ІВЫЬРАТЬ
I РеализацияТоваровУслуг.Ссылка |ИЗ
I Документ. РеализацияТоваровУслуг КАК Реализация! оваровУслуг ІІ'ДЕ
I РеализацияТоваровУслуг.Контрагент = &Контрагент
I И
I (РеализацияТоваровУслуг.Номер < ИХ)
I ИЛИ
I РеализацияТоваровУслуг.Дата < ДАТАВРЕМЯ(2005, I, I))
I И
I РеализацияТоваровУслуг.Товары.Номенклатура В ИЕРАРХИИ(&Номенклатура)"
Запрос.УстановитьПарамстрС'Контрагент '. ОтбКонтрагент); Запрос.УстановитьПараметрС’Номенклатура". ОтбНоменклатура);
Результат = Запрос.Выполнить();
Выборка = Результат.ВыбратьО:
Пока Выборка.Следующий() Цикл
// действия с документом - элементом выборки.
// его значение содержится в переменной Выборка
КонецЦикла;
В данном пример организован перебор всех документов «РеализацияТоваровУслуг» по указанному контрагенту, закупавшему товары из указанной номенклатурной группы ранее 1 января 2005 года или позже, но с номерами документа менее «100».
ф Как пометить на удаление все приходные накладные?
ДокументыВида= Документы.ПоступлениеТоваровУслуг.Выбрать();
Пока ДокумснтыВида.СледующийО Цикл ДокОбъект = ДокументыВида.ПолучитьОбъект(); ДокОбъект.УсгановитьПометкуУдаления(Истина);
Конеці Іикла:
Выполняем выборку приходных накладных. Обходим ее в цикле. Внутри цикла получаем объект документа по каждой из ссылок на накладную. Теперь помечаем документ на удаление при помощи метода УстановитьПометкуУдаления(). В результате документ будет помечен на удаление с вызовом обработчика Перед ЗЭПИСЬЮ
Замечание: как альтернативный вариант - можно было бы внутри цикла просто присваивать реквизиту «ПометкаУдаления» объекта документа значение Истина. Но в этом случае пришлось бы еще обеспечивать и запись документа.
(D Как, имея ссылку на документ, создать в базе его копию?
ДокументКопия = ИсходныйДокумент.СкопироватьО; ДокументКопия.Дата = РабочаяДата;
ДокументКопия.ЗаписатьО;_
При применении метода Скопировать
л) все реквизиты нового документа получают свои значения из переменной «ИсходныйД оку мент». Исключение составляют значения реквизитов «Дата» и «Проведен».
Поэтому, если копирование документа не сопровождается открытием его формы, дату нового документа лучше установить самостоятельно.
В нашем примере в качестве значения реквизита «Дата» устанавливаем дату, которую обычно используют для случаев создания новых документов (получаем из свойства глобального контекста РабочаяДата).
Но если Вам нужно и дату скопировать из документа - источника, то эта строка должна выглядеть следующим образом:
ДокументКопня.Дата = ИсходныйДокумент.Дата:
Ну а потом уже записывать новый документ в базу. В данном случае мы записываем его без проведения.
® Как, имея ссылку на документ, прочитать его движения по регистру?
Если необходимо просто прочитать движения, без последующей модификации - можно воспользоваться запросом к нужному регистру:
Запрос - Новый Запрос;
Запрос.Текст ="ВЫБРАТЬ *
|ИЗ
I РегистрНакопления.ОстаткиНоменклатуры КАК ОстаткнНоменклатуры |ГДЕ
I ОстаткиНоменклатуры.Регистратор = &Регистратор";
Запрос.УстановитьПараметрС'Рсгистратор”. ПолеВводаРегистратор);
В запросе выбираем все поля (кроме виртуальных) из таблицы регистра «РегистрНакопления.ОстаткиНоменклатуры» с отбором по регистратору. Значением параметра «Регистратор» нужно будет установить ссылку на документ.
Если же нужно чтение с последующей модификацией движений -следует воспользоваться объектной моделью представления информации: в свойстве Движения объекта документа обратиться к нужному регистру (в нашем случае это регистр «ОстаткиНоменклатуры») и прочитать набор записей регистра:
НаборЗаписейРегнстра = Движения.ОстаткиНоменклатуры; НаборЗап исей Регистра. П рочитать();
Для Каждого Запись из НаборЗаписейРегнстра Цикл
// Чтение и модификация очередного движения.
КонецЦнкла;
Если требуется изменить движения документа по всем регистрам, нужно обойти фиксированную коллекцию, содержащуюся в свойстве
Движения.
Например:
Для Каждого НаборЗапнсейРегисгра из Движения Цикл НаборЗаписейРегистра.ПрочитатьО;
Для Каждого Запись из НаборЗапнсейРегисгра Цикл
// Чтение и модификация очередного движения.
КонецЦикла;
КонецЦикла;
Сначала открываем цикл перебора свойств свойства Движения -коллекций наборов записей регистров, для которых наш документ является регистратором.
Далее читаем наборы записей каждой коллекции и открываем цикл перебора записей данного набора записей.
Как определить, по каким регистрам документ выполнил движения?
Например, требуется определить, по каким регистрам выполнил движения документ «ВнутреннийЗаказ». Наиболее производительным решением этой задачи будет выполнение следующего запроса к регистрам:
ВЫБРАТЬ ПЕРВЫЕ I
"Внутренние заказы" КАК Регистр ИЗ
РегистрНакопления.ВнутренниеЗаказы КАК ВнутренниеЗаказы
ГДЕ
ВнутренниеЗаказы.Регистратор = &Регистратор
ОБЪЕДИНИТЬ
ВЫБРАТЬ ПЕРВЫЕ 1
"Заказы поставщикам" КАК Регистр ИЗ
РегистрНакопления.ЗаказыПоставщикам КАК ЗаказыПоставщикам
ГДЕ
ЗаказыПоставщикам.Регистратор = &Реі истратор
ОБЪЕДИНИТЬ ВЫБРАТЬ ПЕРВЫЕ 1
"Размещение заказов покупателей" КАК Регистр ИЗ
РегистрНакопления.РазмещеннеЗаказовПокупателеіі КАК РазмешениеЗаказовПокупателей
ГДЕ
РазмешениеЗаказовПокупателей. Регистратор = &Регнстратор
ОБЪЕДИНИТЬ
ВЫБРАТЬ ПЕРВЫЕ 1
"Товары в резерве на складах" КАК Регистр ИЗ
РегистрНакоплсния.ТоварыВРезсрвсНаСкладах КАК ТоварыВРезервеНаСкладах
ГДЕ
ТоварыВРезервеНаСкладах.Регнстратор = &Регистратор
Для каждого регистра, по которому документ «ВнутрениийЗаказ» может выполнять движения, выполняется получение одной первой записи этого регистра, для которой выбранный документ является регистратором (ссылка на выбранный документ должна быть передана в параметр «Регистратор» запроса). В качестве значения выбранного поля получается строка с названием регистра. Результаты всех запросов объединяются.
В результате работы этого запроса может быть получена, например, такая таблица:

Как в табличной части документа удалить строки с нулевым значением реквизита «Количество»?
Если у нас есть ссылка на некоторый уже записанный документ, тогда можно поступить следующим образом:
ОбъектДок = СсылкаДок.ПолучмтьОбъектО;
СтруктураДляПоиска = Новый Структура("Количество", 0);
ТабличнаяЧастьДок = ОбъектДок.Товары;
МассивІ ІустыхСтрок = ТаблнчнаяЧастьДок.НайтиСтроки(СтруктураДляІІоиска);
Для каждого Строка Ил МассивПустыхСтрок Цикл ТабличнаяЧастьДок.Удалить(Строка);
КонецЦнкла;
ОбъектДок. Зашісать();
Получаем по ссылке объект документа. Создаем структуру для поиска. В качестве ключа указываем название реквизита, в качестве значения - искомое значение. Обращаемся к табличной части «Товары» данного документа. Посредством метода НаЙТиСтроки() получаем массив строк соответствующих нашей структуре для поиска. В цикле перебираем эти строки и удаляем их из табличной части документа. После выхода из цикла записываем документ-объект с обработанной табличной частью.
Если же речь идет о еще не записанном документе, и работа выполняется в форме документа, реализация задачи незначительно изменяется:
СтруктураДляПоиска = Новый СтруктураСКоличество”. 0);
МассивПустыхСтрок = Товары.НантиСтроки(СтруктураДляПоиска):
Для каждого Строка Из МассивПустыхСтрок Цикл Товары.Удалить(Строка);
КонецЦнкла;
Изменения связаны с тем, что в этом случае мы сразу находимся в контексте объекта документа. Кроме того, вопрос о записи измененного документа оставляем на усмотрение пользователя штатными средствами.
Как очистить колонку «СтавкаНДС» в табличном поле «Товары» уже заполненного документа?
Для этого нужно «обнулить» значения реквизита «СтавкаНДС» в строках табличной части «Товары» документа. Именно она «отвечает» за данные, представляемые в табличном поле.
При этом не забудьте про обработчик события При изменении, кото может присутствовать в поле ввода этого реквизита.
Например, текст процедуры обработчика:
|
|
|
Процедура ТоварыСтавкаНДСПриИзменении(Элемент)
// Рассчитать реквизиты табличной части. РассчитатьСуммуНДСТабЧастн(ЭлемснтыФормы.Товар
ЭтотОбъект);
КонецПроцедуры // ТоварыСтавкаНДСПрнИзмененннО |
ы.ТекущиеДанные, |
|
Тогда решение нашей задачи будет выглядеть следующим образом: |
|
Для Каждого Строка из Товары Цикл |
|
|
Строка.СтавкаНДС = Неопределено; |
|
|
// Передать управление на процедуру, вызываемую |
|
|
// из обработчика события "ПриИзменении" для поля ввода "СтавкаНДС" |
|
ЭлементыФормы.Товары.ТекущаяСтрока = Строка: |
|
|
РассчитатьСуммуНДСТабЧастнОлементыФормы.Товары.ТекущисДанные. |
|
ЭтотОбъект): |
|
|
КонецЦикла: |
|
|
Открываем цикл перебора строк табличной части «Товары». В цикле устанавливаем значение «Неопределено» для реквизита «СтавкаНДС».
Теперь необходимо выполнить те же действия, что выполнял обработчик интерактивного изменения ставки НДС. И поскольку одним из параметров процедуры РассчитатьСуммуНДСТабЧастиО передается свойство Текущие Да иные табличного поля - сначала позиционируемся на нужной строке табличного поля. Теперь передаем управление нужной процедуре.
Какзаполнитьзначения свойств нового документа на основании существующего?
Для этого можно воспользоваться методом глобального контекста ЗаполнитьЗначенияСвоЙСТВ(), который позволяет копировать значения свойств одного объекта в свойства другого объекта:
НовыйСнет = Документы.СчетНаОнлатуПокуиатслю.СоздатьДокументО; ЗаполнитьЗначенияСвойств(НовыйСчет, ДокументЗаказа,, "Дата");
// Заполнить табличную часть Товары.
Для Каждого СтрокаТоваровЗаката Из ДокументЗаказа.Товары Цикл ЗамолнитьЗначснияСвойствІ НовынСчет.Товары.ДобавитьІ).
СтрокаТоваровЗаказа);
КонецЦикла;
// Заполнить табличную часть ВозвратнаяТара
Для Каждого СтрокаТарыЗаказа Из ДокументЗаказа. ВозвратнаяТара Цикл ЗаполнитьЗначенияСвойств(НовыйСчет.ВозвратнаяТара.Добавить(),
СтрокаТары Заказа);
КонецЦикла;
// Заполнить табличную часть Услуги
Для Каждого СтрокаУслугЗаказа Из ДокументЗаказа.Услуги Цикл ЗаполннтьЗначснняСвойствШовынСчет.Услуги.ДобавнтьО. СтрокаУслугЗаказа): КонецЦикла;
НовынСчет.ЗаказПокупателя = ДокументЗаказа;
Форма = НовыйС'чет.ПолучитьФормуО: Форма.ОткрытьО;
Как получить перечень приходных накладных, в которых не заполнены номенклатурные позиции?
Запрос = Новый Запрос:
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ
1 ПриходпаяТовары.Ссылка как Накладные |ИЗ
1 Документ.ПоступлениеТоваровУслуг.Товары КАК ПрмходнаяТовары і |
|ГДЕ
1 ПрмходнаяТовары.Номенклатура = &ПустаяНоменкла |
ура"; |
Запрос.УстановитьПараметр( "ПустаяНоменклатура",
Справочники.Номенклатура |
.ПустаяСсылкаО); |
|
ТаблицаНакладных = Запрос.ВыполнитьО; |
|
Выполняем запрос по табличной части «Товары» приходных накладных. Делаем отбор по равенству поля «Номенклатура» параметру « ПустаяНоменклатура».
В качестве значение параметра устанавливаем пустую ссылку справочника «Номенклатура».
Результат запроса будет состоять из единственной колонки «Накладные».
Обратите внимание - выбираем не повторяющиеся записи (ВЫБРАТЬ РАЗЛИЧНЫЕ). наличия
нескольких строк с незаполненной номенклатурой в одном документе.
Как на дату расходной накладной определить курс валюты управленческого учета? Валюта управленческогоучета храниться в периодическом регистре сведений.
Информацию о валюте управленческого учета хранит регистр сведений «УчетнаяПолитика» - периодический, с периодичностью год:
'Ш УчетнаяПолип#;а . . Иэмере**<я В-1 Ресурсы
I |— I ВалютаУправпемческая I '— § М етааСписаміяП артий h-f Реквизиты
Регистр сведений «КурсыВалют» - так же периодический, но с периодом «день»:
- $ Курсыбалют ? . Измерения
L-t. Ва/юта В
т Ресурсы hi Курс '— I Кратность « Реквизиты
Данную информацию можно получить посредством запроса:
ВЫБРАТЬ
КурсыВалютСреіПоследних.Валюта как ВалютаУпр,
Курсы Вал ютС реч Пос;іедн и х. Ку ре как КурсУпр ИЗ
Реі исгрСвелений. КурсыВал ют.СретПоследних(&ДатаДокумента. Валюта В ( ВЫБРАТЬ
У чегн аяПолитикаСретПоследних.Вал ютаУ правлен чес кая ИЗ
РсгнстрСведений.УчетнаяПолитнка.СрезПоследних(&ДатаДокумснта, ) КАК УчетнаяПолнтикаСрезПоследних)
) КАК КурсыВалютСретПоследних
Во вложенном запросе осуществляем определение управленческой валюты на дату документа. Результатом будет таблица с единственной валютой. Данную таблицу используем при построении отбора на параметрах виртуальной таблицы
«РегистрСведений. Курсы Валют. СрезПоследних». Поскольку
управленческих валют - только одна, на выходе запроса получим таблицу из единственной записи с двумя полями «ВалютаУпр» и «КурсУпр».
Как из формы документа вызвать его неоперативное проведение?
В форме документа кнопке «ОК» обычно назначается действие «записать и закрыть», обеспечивающее выполнение стандартных операций по записи, проведению документа и закрытию формы. Одной из таких операций, при определенном перечне условий, является уточнение у пользователя режима проведения документа (оперативно или неоперативно).
В случае если для проведения документа это никакой роли не играет, и пользователя раздражает подобная «любознательность» системы, можно сделать следующее:
-удалить стандартную кнопку;
- создать свою кнопку;
- в качестве действия назначить нижеприведенную процедуру.
Процедура ОсновныеДействияФормыОК(Кнопка)
ЭтаФорма. Испод ьзоватьРежимПроведения — Испод ьзованиеРсжимаПровелсння
.Неоперативный:
ЗаписатьВФорме(РежимЗаписиДокумента.Про ведение):
Закрыть();
КонецПроцсдуры
В процедуре свойству ИспользоватьРежимПроведения
расширения формы документа назначаем значение Неоперативный из соответствующего системного перечисления.
Далее используем метод ЗаписатьВФорме() расширения формы документа. В результате управление последовательно будет передано на нужные обработчики событий, начиная с Перед записью формы документа.
Последней командой процедуры форма документа закрывается.
Как в обработке проведения получить остатки, актуальные на позицию документа?
Корректно вопрос решается за счет использования параметра «Период» виртуальной таблицы:
Для запроса вида:
Запрос.Текст = " ВЫБРАТЬ
I ВзаиморасчетыСКонтрагентамиОстаткн.СуммаВзаиморасчетовОстаток,
I ВзаиморасчетыСКонтрагентамиОстатки.СуммаУпрОстаток |ПЗ
I РегистрНакоплення.ВзаиморасчетыСКонтраіентами.Остатки(&1ІараметрПериод.
ДоговорКонтрагснта = &Договор И Сделка =&Сделка) ( КАК ВзаиморасчетыСКонтрагентамиОстатки";
он должен устанавливаться следующим образом:
Запрос.УілановіпьПараметрГПараметрПериод". МомеитВремениО):
Необходимо обеспечить расчет данных по всем активным записям документов, введенных ДО текущего. Именно поэтому в качестве параметра передается момент времени документа, а не дата документа. Точность реквизита «Дата» - дата (минимальная дробность - секунда). А у момента времени - дата и ссылка.
То есть, если есть несколько документов с одной и той же датой система за счет метода МоментВремени() точно определит - кто из них первый, кто второй, кто - следующий.
Замечание: обратите внимание на применение условий отбора данных по значениям измерений именно за счет параметров виртуальной таблицы уже при ее построении. Это обеспечивает большую скорость построения запроса, нежели применение ГДЕ.
Как определить количество документов и количество разных значений реквизита в таблице записей документа?
По данным документа «РегистрацияПростоевВОрганизации»
- Z РегистрацияЛростоеевОргамизацж ?з Реквизиты
—— Организация — Комментарий
- Ответственный
— ПермодРегист рации - — Физлицо
- Приказ
— ВиоПростоя — Дат «Начала
- Дат «Окончания В і.
:2, Т абличные части
© ЕІ] На-аслеиия В ііІ, Расчет Среднее о
ВЫБРАТЬ
КОЛИЧЕСТВО(РегистрацняПростосвВОрганитации.Ссылка) КАК Случаев. КОЛИЧЕСТВО!РАЗЛИЧНЫЕ РегистраиняПростоевВОрганизации.ФнхПицо) КАК Работников ИЗ
Доку мент. РегистрацияПростосвВОрганиіации КАК Реі истрацияПростоевВОрганизации
ГДЕ
(РегистрацияПростоевВОрганизации.Проведен)
Источником является таблица документа
«РегистрацияПростоевВОргнаизации».
В качестве выходных полей получим значения агрегатной функции КОЛИЧЕСТВОО по отношению к полям «Ссылка» и «ФизЛицо». Причем подсчитываются только различные значения поля «ФизЛицо».
Поскольку группировочные поля не указаны, результатом запроса будет таблица, состоящая из одной строки.
Значения этой строки по каждой из колонок и дадут требуемые данные.
В последовательность «ПартионныйУчет» добавлено измерение «Организация». Как теперь получить данные по границам последовательности для каждого значения этого измерения?
Для получения таблицы значений, в первой колонке которой будут указаны границы последовательности, а в последующих - значения измерений - можно применить метод последовательности
ПолучитьГраницы():
ТаблицаГраниц = Последовательности .ПартионныйУчет . ПолучитьГраннцы( "Организация");
Для Каждого СтрокаТаблицыГраниц из ТаблицаГраниц Цикл Организация = СтрокаТаблицыГраниц.Организация; ДатаГП = СтрокаТаблицыГраниц.Граница.Дата:
СсылкаГП = СтрокаТаблицыГ раннц. Граница.Ссылка: КонецЦнкла;
В качестве параметра методу достаточно передать название измерения (если нужно несколько - можно через запятую).
Далее в цикле перебираем полученную таблицу значений, считывая данные из колонки «Граница» и колонки «Организация».
Замечание: если границы нужны не все (по организациям), а только наименьшая из них - лучше применять метод ПолучитьГраницу(). Он возвращает уже не таблицу, а именно - момент времени.
Хранение сведений
Ф Как добавить запись в непериодический независимый регистр сведений?
Для непериодического регистра сведений:
% Зиаче»«4яСк>йсте Измерения ь-t. Номег* оатурз ! ‘—L Свойство
0 Ресурсы
1 *— I Значение з Реквизиты
|
НаборЗаписей = РегистрыСведений.ЗначенияСвойств.Сі |
здатьНаборЗаписей(): |
|
НаборЗаписей.Отбор.Номенклатура.Установить(ТекущаяНоменклатура); НаборЗаписей. Отбор.Свойство. У становить(ТекущееСвойство); |
НоваяЗапись = НаборЗаішсей.ДобавитьО;
Новая Запись. Номенклатура = ТскущаяНоменклатура; НоваяЗапись.Свойство = ТекущееСвойство:
Новая Запись. Значение = ТекущееЗначсние; |
|
|
НаборЗаписей.ЗаписатьО; |
|
Создаем набор записей нашего регистра сведений.
Далее применяем отборы по нужным полям. Как правило - по измерениям, входящим в основной отбор.
Создаем новую запись, заполняем ее поля.
Записываем новый набор записей с замещением всех записей, соответствующих отбору. Параметр «Замещение» метода Записать() по умолчанию имеет значение Истина.
Для чего нужно замещение?
Дело в том, что в любом регистре запись с конкретным ключом записи всегда уникальна. Для непериодического независимого регистра сведений ключом записи является конкретная комбинация значений измерений.
То есть запись с определенной комбинацией значений измерений может присутствовать только в единственном экземпляре. Попытка записать новую запись с тем же набором значений измерений привела бы к ошибке.
Кроме того, в подобной работе можно удариться в другую крайность.
Если не применить отбор, то при записи система попытается заместить все существующие записи регистра. В результате, добавляя новый набор записей с замещением, - мы бы удалили все ранее введенные записи регистра!
ф Как считать содержимое непериодического независимого регистра сведений? «СобственныеКонтрагенты»?
НаборЗаписей = РегистрыСведений
.СобственныеКонтрагенты .Создать!! аборЗаписей!): НаборЗаписей.Прочитать! I;
// Перебрать записи в цикле...
Для Каждого Запись из НаборЗаписей Цикл РегистрКонтрагснт = Заиись.Контрагент; РегистрВидСвязи = Запись.ВидСвязи; РеіистрОбъекг = Запись.Объект: КонецЦикла
И ... или выгрузить записи в таблицу значений ТаблицаЗаписей = НаборЗаписей.Выгрузить!):
Сначала создаем переменную «НаборЗаписей», в которую считываем все записи регистра. Считанные записи можно выгрузить в таблицу значений или перебрать в цикле перебора коллекции. Внутри цикла переменная «Запись» предоставит доступ к самой записи. Например, для считывания содержимого полей записи.
Кроме того, эти же данные можно получить посредством запроса со следующим текстом:
ВЫБРАТЬ
*
ИЗ
РегистрыСведений.СобствешіыеКонтрагенты
В дальнейшем результат выполнения запроса можно также выбрать или выгрузить на таблицу значений.
(D Как удалить все записи из независимого регистра сведений?
НаборЗаписей = РепістрыСвсдснпй.ТоріовоеОборудование.СогдатьНаборЗапнсей(): НаборЗаписей.Запнсать();
Создаем переменную «НаборЗаписей» как набор записей регистра сведений. Поскольку мы не прочитали данные из регистра - в этот момент это пустой набор записей.
Записываем новый набор записей (пустой) с замещением всех предыдущих записей (по умолчанию параметр «Замещать» метода Записать() имеет значение Истина).
Замечание: данную технологию можно применять только для регистров сведений с независимым режимом записи.
<Э Как удалить записи независимого регистра сведений с отбором по конкретной организации?
Структура независимого регистра сведений
«ОбъектыСтроительстваОрганизаций» следующая:
ОбьектыСтроигельстваОргаиизацмй
ЁНІ-. Измерения
I ' - Организация
' . ОбъегтСтроительства Q- *
и Ресурсы
|~ I СчетБухга/ттерскогоУчета I— I СчетБухга/тгерскогоУчетаНДС
НаборЗаписей = РегистрыСведеннй
.ОбъектыСтронтельстваОргашпаций .Соідаі ьі ІаборЗаписейІ);
НаборЗаписей.ОтборОргашпация.Усі ановить(УдаляемаяОрганизация): НаборЗаписей.Записать();
Создаем переменную «НаборЗаписей», устанавливаем для нее отбор по значению организации равный «УдаляемаяОрганизация». Кстати, отбор набора записей регистра всегда может устанавливаться только на равенство.
Далее записываем полученный пустой набор записей с замещением.
В результате все записи, соответствовавшие отбору, будут замещены пустым набором записей.
Замечание: данная задача не может решаться без комплексного рассмотрения вопроса устойчивости и целостности базы данных, поскольку на данные регистра могут быть «завязаны» учетные механизмы конфигурации.
© Как добавить запись в периодический независимый регистр сведений?
Для периодического независимого регистра сведений так же актуально все сказанное про непериодический регистр сведений (см. вопрос «Как добавить запись в непериодический независимый регистр сведений?» на странице 124). Только по другому строится ключ записи -добавляем еще один отбор по полю «Период».
Ь КурсыВалют
В-Д-* Измерения *— і— Валюта
в- г* Psc*>c4 к**
I— I Кратность Реквизиты
НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписсйО:
НаборЗаписей.Отбор. ІЗалюта.У становить(Т екущая Валюта): НаборЗаписей. Отбор.Периол.Установить(ТекущаяДата):
НовЗапись = НаборЗаписей.ДобавитЦ):
НовЗапись.Валюта = ТекущаяВалюта:
НовЗапись. Период = ТекущаяДата:
НовЗапись.Курс = ТекущийКурс:
НовЗапнсь.Кратность = ТскушаяКратность:
НаборЗаписей.Записать(Истииа);
ф Как прочитать (изменить) записи в периодическом независимом регистре сведений?
Отличие технологии чтения (изменения) записей периодического регистра сведений от непериодического только в работе с полем «Период».
В примере ниже представлен вариант чтения данных периодического регистра сведений «Валюты» на дату «ДатаЗаписи», сообщение данных полей каждой записи и обнуление значения курса попавших в отбор записей:
НаборЗаиисей = РегистрыСведений.Валюты.СоздатьНаборЗаписей!) НаборЗаписей.Отбор.Период.Установить(ДатаЗаинсн);
НаборЗаписей.Прочитать!);
Для Каждого Запись Из НаборЗаиисей Цикл
// Чтение и сообщение данных полей записи. Сообщить(Строка(Запись.Период) + ”" +
Строка(Запись.Валюта) + " " +
Как удалить записи в периодическом независимом регистре сведений?
Удаление всех записей периодического независимого регистра сведений выполняется так же, как и для непериодического независимого регистра сведений:
НаборЗаписей = РегистрыСведений.КурсыВалют.СоздаіьНаборЗаписейО; НаборЗаиисей. Заііисать();
Создаем переменную «НаборЗаписей» как набор записей регистра сведений. Поскольку мы не прочитали данные из регистра - в этот момент это пустой набор записей.
Записываем новый набор записей (пустой) с замещением всех предыдущих записей (по умолчанию параметр «Замещать» метода Записать() имеет значение Истина).
Замечание: данную технологию можно применять только для регистров сведений с независимым режимом записи.
Как в периодическом независимом регистре сведений «КурсыВалют» удалить все записи по валютам с наименованиями «EUR» и «USD», период которых меньше 01 января 2005 года?
Один великий скульптор на вопрос «Как вам удалось создать такой шедевр?» ответил: «Отсек все лишнее!».
Примем на вооружение метод, но... перевернем его. В данной задаче у нас просят отсечь все лишнее, а решить ее можно - оставив все нужное.
Поэтому сначала получим таблицу записей, которые необходимо оставить. Поскольку условий несколько, да еще и не все они на равенство - оптимальнее это сделать при помощи запроса.
Следующий запрос даст нам желаемое:
Запрос = Новый Запрос;
Заирос.Тскст = "ВЫБРАТЬ
I *
|ИЗ
I РегистрСведений.КурсыВалют КАК КурсыВалют |ГДЕ
I (КурсыВалют.Период >= ДАТАВРЕМЯ(2005. 1.1)
I ИЛИ
I НЕ(Курсы Вал ют. Вал юта. Наименование ПОДОБНО ""USD"")
I И
I НЕ(КурсыВалют.Валюта.Наименование ПОДОБНО ""EUR""))'
Источником данных для запроса послужила таблица записей регистра.
Были применены отборы, чтобы в результат попали записи, для которых период более или равен 01 января 2005 года или наименования не «USD» и не «EUR». Обратите внимание, при составлении условия по периоду, чтобы не пользоваться параметром запроса, прямо в тексте запроса применили литерал даты ДАТАВРЕМЯ(), в котором части даты указываются в «обратном» порядке: год, месяц, порядковый номер дня в месяце.
Результатом запроса будет таблица, в которой по каждой записи заполнены все поля регистра сведений «КурсыВалют».
ТаблицаОставляемыхЗаписсй = Запрос. Выполнить().Выгруэить();
НаборЗаписсй = РегистрыСведений.КурсыВалют.СоздатьНаборЗапнсей();
НаборЗаписсй.Загрузить(ТаблицаОставляемыхЗаписей):
НаборЗаписей.ЗаписатьО;
Далее запрос выполняем, выгружаем результат в таблицу значений «Т аблицаОставляемыхЗаписей».
Создаем переменную «НаборЗаписей», тип значения РегистрСведенийНаборЗаписей.КурсыВалют, выгружаем в нее таблицу значений «ТаблицаОставляемыхЗаписей».
Поскольку сама таблица была получена из регистра - то названия ее колонок совпадут с названиями полей регистра - а значит, загрузка пройдет успешно.
Далее записываем заполненный только нужными записями набор записей в регистр с замещением его исходных данных (как Вы уже помните, параметр «Замещать» метода Записать() по умолчанию имеет значение Истина).
Замечание: данная задача не может решаться без комплексного рассмотрения вопроса устойчивости и целостности базы данных, поскольку на данные регистра могут быть «завязаны» учетные механизмы конфигурации.
Как прочитать данные, актуальные на определенную дату, из регистра сведений «Курсы валют» с отбором по нескольким валютам (отбор по измерениям)?
Для решения данной задачи удобнее всего использовать запрос. Например:
Запрос = Новый Запрос:
МассивВалют = Новый Массив:
МассивВалют.Добавить( Валюта 1);
МассивВалют.Добавить( Вал юта2):
Запрос.УстановитьПарамстрС’МассивВалют", МассивВалют); Запрос.УстановитьІ Іарамстр( "ДатаПолучения", ДатаПолучения);
Заирос.Текст = "
ІВЫБРАТЬ
I ВалютыСрезПоследних.Валюта.
I ВалютыСрезПоследних.Курс |ИЗ
I Регистреведений.КурсыВалют.СрезПоследних(&ДатаПолучения.
Валюта В (&МассивВалют))
КАК ВалютыСрезПоследних";
ТаблицаКурсов = Запрос.Выііоііниіь().Выгрузить));
Создаем запрос. В качестве параметров запроса передаем массив валют, по которым мы хотим получить данные и значение даты, на конец которой нужно получить срез последних.
Запрос строим по виртуальной таблице
«РегистрСведений. КурсыВалют. СрезПоследних» регистра
«КурсыВалют». В качестве параметров виртуальной таблицы указываем дату построения и условие по измерению валюта (значения измерения должны входить в переданный массив).
Как поменять период у записей периодического независимого регистра, соответствующих ряду условий?
В периодическом независимом регистре сведений «ОтветственныеЛицаОрганизации» все записи, касающиеся организации с наименованием «Групи-трейдинг», период которых меньше 01 января 2005 года необходимо перенести на 01 января 2004 года. Но записи с указанием должностей «Продавец» и «Кладовщик» должны остаться на своих местах.
Структура регистра следующая:
Ответственные Л ицаО рг «ни зацим . Измерения
і 1—t . СтруктурнаяЕдиннца ! I— I. ОтветственмоеЛ то В С Ресурсы
І— і Физическое Лицо Должность
Измерение «СтруктурнаяЕдиница» имеет тип значения СправочникСсылка.Организации.
Для периодического независимого регистра сведений модифицировать (и удалять) записи можно только посредством объекта РегистрСведенийНаборЗаписей.<имя> или
РегистрСведенийМенеджерЗаписи.<имя>.
И в том и в другом случае понадобится работать с отборами по периоду (обязательно) и по измерениям (желательно, в зависимости от контекста задачи).
Поэтому сначала получим таблицу записей, которые подлежат модификации. Поскольку условий несколько, да еще и не на равенство -оптимальнее это сделать при помощи запроса. А потом, перебирая результат запроса, добьемся требуемого результата:
Процедура ЗаменаІ 1ериода()
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ I ОтветственныеЛицаОрганизации.Период.
I ОтветственныеЛицаОрганизации.Структурная Единица. I ОтветственныеЛицаОрганизации.ОтветственноеЛицо |ИЗ
I РегнстрСведенин.ОтветственныеЛнцаОрганизации
КАК ОтветственныеЛицаОрганизации
|ГДЕ
I ОтветственныеЛицаОрганизации.Период <= ДАТАВРЕМЯ(2005, 1, 1)
I И
I ОтветственныеЛицаОрганизации.СтруктурнаяЕдиница.Наименование
ПОДОБНО Трупп-Трейдинг' I И
I (ОзветсгвенныеЛицаОртапизацни.Должиость.Наименование ЕСТЬ NULL ИЛИ
I НЕ(ОтветственныеЛнцаОрі анизации. Должность. Наименование
ПОДОБНО "Продавец"
ИЛИ
ОтветственныеЛицаОрганнзации.Должность.Наимснованис
ПОДОБНО "Кладовщик"))”:
Результат = Запрос.Выполнить():
Выборка = Результат.ВыбратьО;
Запись = РегистрыСведений
.ОтветственныеЛицаОрганизации
.СоздатьМенеджерЗаписиО:
Пока Выборка.СледующийО Цикл Запись. I Іериод = Выборка.Период;
Запись.СтруктурнаяЕдиница = Выборка.С'ірукгурнаяЕднница: Запись.ОтветственноеЛнцо = Выборка.ОтветственноеЛ ицо;
Запись.Прочитать));
Если Запись. Выбран)) Тогда Запись.Период = Дата(2004,1,1);
3апись.3аписать();
КонецЕсли;
КонецЦикла;
КонецПроцедуры;_
Результат запроса - таблица, в которой по каждой записи заполнены все поля измерений из регистра и поле «Период». Именно эту информацию мы используем для получения каждой нужной записи.
Источником данных для запроса послужила таблица «РегистрСведений. ОтветственныеЛицаОрганизации».
Были применены отборы так, чтобы в результат попали записи с периодом менее 1 января 2005 года, наименование структурных единиц, в которых - «Групп-трейдинг», а наименования должностей не относятся к «Продавец» и «Кладовщик». Кроме того, необходимо позаботиться о
случае, когда должность вообще не указана - то есть ее наименование имеет значение NULL. Такие записи тоже нужно будет переносить.
Запрос выполнен, далее перебирая его результат и посредством менеджера записи регистра «ОтветственныеЛицаОрганизации» добиваемся желаемого. При каждом проходе никла считываем очередную запись, предварительно указав значение ее поля «Период» и полей измерений.
Далее меняем значение поля «Период» у считанной записи и записываем ее в регистр.
Как «сделать периодическим» реквизит уже заполненного справочника?
У справочника «Проекты» есть реквизит «Ответственный» (тип значения - СправочникСсылка. Пользователи). Необходимо обеспечить в системе возможность «перезакрепления» проектов за ответственными с сохранением истории значений с точностью до дня.
Для хранения истории значений периодических данных в системе «1С:Предприятие 8.0» используют регистры сведений.
Поэтому для красивого решения нашей задачи понадобится
выполнить следующие шаги:
Создать в системе периодический регистр сведений
«ЗакреплениеПроектов».
Создать и выполнить обработку, которая заполнит новый регистр информацией из уже заполненных элементов справочника.
Проконтролировать и обеспечить корректность работы всех механизмов системы, использовавших реквизит «Ответственный» справочника «Проекты». Для поиска таких механизмов можно, например, воспользоваться командой «Правка | Глобальный поиск ...». Корректность необходимо проверять по поводу последующего хранения информации об ответственных в периодическом регистре сведений и по поводу последующего удаления реквизита «Ответственный» из справочника «Контрагенты».
Удалить реквизит «Ответственный» из структуры справочника «Проекты».
Обеспечить удобство для пользователей визуализации, ввода и редактирования информации об ответственных за проекты. В самом простом для разработчика случае - можно просто убедиться в доступности кнопки «Перейти» в командных панелях формы списка и формы элемента справочника «Проекты».
Рассмотрим первые два шага более подробно:
1) Создание периодического регистра сведений.
Если не требуется регистрировать факты
закрепления/перезакрепления посредством специального документа -режим записи регистра будет «Независимый». Периодичность регистра определяется спецификой бизнес-процессов автоматизируемого предприятия, в нашем случае - «День».
Поскольку по каждому проекту в конкретный момент времени будет один ответственный — то структура регистра будет следующей:
В ? ЗекрепленмеЛроектов В * Иэмеретыя *• . Проект f
u Ресурсы *— j; Ответствен****
3 Реквизиты
Тип значения измерения «Проект» - СправочникСсылка.ПрОбКТЫ. Не забудьте указать для данного измерения свойство «Ведущее», тогда при удалении проектов будут автоматически удалены и соответствующие им записи регистра сведений. Тип значения ресурса «Ответственный» -СправочникСсылка. Пользователи.
2) Обработка заполнения регистра по существующим данным справочника.
Код этой обработки может выглядеть следующим образом:
Запрос - Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ I &ДатаУстановкм КАК Период,
I Проекты.Ссылка КАК Проект,
I Проекты.Ответственный |ИЗ
I Справочник.Нроекты КАК Проекты |ГДЕ
I (НЕШроекты.'ЗгоГ руппа)) И (НЕ(Проекты.Ответственный = «^Ответственный))"
Запрос.УстановитьПараметр('Ответственный',
Справочники.Пользе ватели.ПустаяСсылкаО);
Запрос. УстановнтьПараметрС'ДатаУстановки", Дата(2000,1.1));
ТаблицаРезультат = Запрос.ВыполнитьО.ВыгрузитьО;
НаборЗаписей = РеіистрыСведений.ЗакреплениеПроектов.СоздатьНаборЗаписейО: НаборЗаписей.Загрузить(ТаблицаРезультат);
I ІаборЗап исей .Записать();
Имеет смысл выполнять обработку только по элементам справочника «Проекты» (по группам не нужно) и только по тем элементам, у которых заполнен реквизит «Ответственный». Получение необходимой информации организуем посредством запроса.
Источником данных для него будет таблица «Справочник.Проекты». Применяем вышеописанные условия. Состав и псевдонимы выходных полей запроса делаем соответствующим составу и именам полей записей регистра.
Поскольку невозможно в периодический регистр сведений внести записи с пустым значением поля «Период», и в справочнике не хранилась информация, с какого момента были закреплены ответственные за проектами - через параметр запроса назначаем значение периода заведомо предшествующее началу работы с нашей базой.
Результат выполнения запроса выгружаем в таблицу значений «Т аблицаРезул ьтат».
Далее создаем переменную «НаборЗаписей» соответствующего типа значения.
Поскольку имена полей записей регистра совпадают с названием колонок таблицы - таблицу значений «ТаблицаРезультат» загружаем в набор записей регистра «ЗакреплениеПроектов».
Далее записываем заполненный набор записей.
Обратите внимание, что в нашем случае набор записей регистра создавался без отборов и у метода Записать() значение параметра «Замещать» было опущено (значит, по умолчанию равно Истина). В результате, даже если какие-то записи существовали в регистре до начала выполнения обработки, - они будут полностью замещены новыми, сформированными обработкой. Подобное действие (замещение всех записей регистра) возможно только для регистров сведений с режимом записи «Независимый» (то есть, не подчинены регистратору).
Если регистр сведений подчинен регистратору, то для добавления записей в такой регистр необходимо создать набор записей этого регистра с установленным отбором по нужному регистратору, заполнить этот набор записей и записать его:
НаборЗаписей = РегистрыС ведений
.ЛнмитыВотвратнонТары
•СоздатьНаборЗаписейО;
НаборЗаписей.Отбор. Регистратор.Установить(ВыбранныйРегистратор);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись. Период = ВыбранныйРегистратор.Дата:
Новая Запись. Номенклатура = ВыбраннаяНоменклатура: НоваяЗапись.ДоговорКонтрагента = ВыбранныйДоговор; НоваяЗапись.ЛнмитПоставщика = 50;
НаборЗал леей. Записать!):
По-умолчанию запись выполняется с замещением, т.е. существующие записи этого регистратора в регистре сведений будут удалены.
Для того чтобы добавить записи к существующим записям регистратора, необходимо указывать значение ЛОЖЬ параметра метода Записать() набора записей. При этом необходимо позаботиться о том, чтобы значения измерений добавляемых записей были уникальны для записей данного регистратора в регистре сведений, иначе запись выполнена не будет:
НаборЗаписей = РсгистрыСвсдений
.Л нмитыВотвратнойТ ары .СочдатьНаборЗаписейО:
НаборЗаписей. Отбор. Регистратор. Установить! Выбранный Регистратор):
НоваяЗапись = НаборЗаписей .ДобавитьО;
НоваяЗапись.Период = ВыбранныйРегистратор.Дата; НоваяЗапись.Номенклатура = ВыбраннаяНоменклатура; НоваяЗапись.ДоговорКонтрагента = ВыбранныйДоговор:
Новая Запись-ЛимитПокупателю = 25;
НаборЗаписей. Записать(Ложь);
Для того чтобы прочитать данные регистра сведений, подчиненного регистратору, необходимо создать набор записей, установить отбор по регистратору и затем выполнить метод Прочитать() набора записей регистра сведений. После этого можно перебрать записи набора в цикле и выполнить необходимые изменения.
В примере ниже представлен вариант чтения данных регистра сведений «ЦеныНоменклатуры» для документа
«ВыбранныйРегистратор», сообщение данных полей каждой записи и обнуление процента скидки для записей этого документа в регистре сведений:
НаборЗапнсей = РегистрыСведений.ЦеныНоменклатуры.('оздатьНаборЗаписей():
НаборЗаписей.Отбор.Регистратор.Установить(ВыбранныйРегистратор);
НаборЗапнсей. Прочитать));
Для Каждого Запись Из НаборЗапнсей Цикл
// Чтение и сообщение данных полей записи. Сообщить(Строка(Запись.Период) + "" +
Строка(Запнсь.ТипЦен) +" ’’+
Строка)Запись.Номенклатура) + " " +
С грока(Запись.Цена) + " ” + Строка(Замнсь.ПроцентСкидкиНаиенки));
// Изменение данных полей записи.
Запись.ПроцентС кидкиНацснки = 0;
КонецЦикла;
НаборЗапнсей.Записать)):
Прежде всего, следует оценить необходимость решения такой задачи. Если записи в регистр попадают при проведении регистраторов, и у документов-регистраторов свойство «Удаление движений» имеет значение «Автоматическое удаление движений» - то достаточно просто отменить проведение всех регистраторов - и движения будут удалены из регистра. Именно такая картина наблюдается в большинстве случаев.
Если же задача заключается в очистке таблицы записей регистра в некоторых регламентных целях, можно поступить следующим образом:
Запрос = Новый Запрос:
Запрос.Тскст ="
|ВЫ БРАТЬ
I ЦеиыНоменклатурыКонтрагентов.Регистратор |ИЗ
I РегистрСведений.ЦеныНоменклатурыКонтрагентов КАК ЦсныНомснклатурыКонтрагентов";
Результат = Запрос.ВыполнитьО:
Выборка = Результат.ВыбратьО;
НаборЗаписей = РегистрыСведений
.ЦсныНомснклатурыКонтрагентов
.СоздатьНаборЗаписейО:
Пока Выборка.СледующийО Цикл
НаборЗап исей.Отбор. Регистратор. Установить! Выборка. Регистратор); НаборЗаписей.Записать();
КонецЦикла;
Сначала запросом получаем выборку всех документов, являющихся регистраторами для нужного регистра.
Далее создаем набор записей по данному регистру.
В цикле перебора выборки из результата запроса - устанавливаем отборы для набора записей по нужным регистраторам и записываем пустые наборы записей в регистр с замещением старых наборов.
Бухгалтерский учет
© Как в регистре бухгалтерии сформировать проводки?
Допустим, требуется сформировать следующую проводку для операции оплаты поставщику:
|
Счет дебета |
60.01 |
|
Контрагент |
LIGHT |
|
Договор |
Основной договор |
|
Документ |
Документ расчета с контрагентами №2 |
|
Счет кредита |
51 |
|
Банковский счет |
р/с завода Инвестспецбанк |
|
Статья движения денежных средств |
Оплата за оборудование |
|
Сумма |
300 000 |
|
Содержание |
Оплата поставщику |
|
Номер журнала |
БК |
Согласно этим данным, проводка должна быть сформирована по регистру бухгалтерии «Хозрасчетный»:
0 Щ Хозрасчетный Измерения j— L* Организация
=.....I— Валюта
Й ¦Ресурсы I Сумма
і ВалютнаяСумма I Количество В S Реквизиты
— Содержание — НомерЖурнала
|
Данную задачу можно решить следующим образом: |
|
// Задать выбираемые значения. ВыбранныйОтветственный = Справочники |
|
|
.Пользователи |
|
|
.НайтиПоНанменованию(" Иванцова"): |
|
Выбранный Контрагент = Справочники.Контрагенты. Пай |
гиПоКоду("00027"): |
|
ВыбранныйДоговор = Сі іравочники.Договоры Контрагентов. НайтиІІоКодуС'ООО 13”); ВыбранныйДокумент = Документы
.ДокументРасчетовСКонтрагентом .НайтиПоНомеру(2, '2005010Г);
ВыбранныйСчет = Справочники.БанковскиеСчета.НайтнПоКодуС'00001 ВыбраннаяСтатья = Справочники
.СтатьиДвиженияДенежныхСредств
.НайтиПоКодуС00002
п);
ВыбраниаяОрганитация = Справочники.Организации.НайтиПоКодуС'ООООГ'): Выбранная Валюта = Справочники. Валюты. НайтиПоКоду(8І0);
// Создать будущий рег истратор.
ДатаЗаписи = ТекущаяДатаО;
Документ = Документы.ОперацияБух.СоздатьДокументО;
Документ.Дата = ДатаЗаписи;
Документ.Организация = ВыбраннаяОртанизация:
Документ.Ответственный = ВыбранныйОтветственный;
Документ.Содержаніге = "Оплата поставщику";
Документ.ЗаписатьО;
// Создать набор записей.
НаборЗапнсей = РетистрыБухгалтерни.Хозрасчетный.СоздатьНаборЗаписейО; ІІаборЗаписсй.Отбор.Регнстратор.Установить(Документ.Ссылка);
Движение = НаборЗаписей.ДобавитьО;
Движеггие.Ретистратор = Документ.Ссылка;
Движение.Пернод = ДатаЗаписи:
// Заполнить счет дебета.
Движение.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКодуС'60.01 // Заполнить аналитику счета дебета.
Движение.СубконтоДт.Контрагенты = ВыбранныйКонтрагент; Движение.СубконтоДт.Договоры = ВыбранныйДоговор;
Движение.СубконтоДт.ДокументыРасчетовСКонтрагентами= ВыбраггныйДокумент; // Заполнить счет кредита.
Двнжение.СчетКт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("5Г');
// Заполнить аналитику счета кредита.
Движение.СубконтоКт.БанковскиеСчета = ВыбранныйСчет; Движение.СубконтоКт.СтатьиДвиженияДенежныхСредств = ВыбраннаяСтатья:
// Балансовое измерение.
Движенис.Организация = ВыбраннаяОртанизация;
// Балансовый ресурс.
Движение.Сумма = 300000; ,
// Реквизиты.
Движсние.НомерЖурнала = "БК"; Движение.Содержанне = "Оплата поставщику'
// Записать набор 'записей.
НаборЗаписей.Записать();
Внести информацию в регистр бухгалтерии без привязки к документу-регистратору невозможно. Поэтому, например, в составе типового решения «Бухгалтерия предприятия» для работы с так называемыми «ручными операциями» существует документ «ОперацияБух». Его задача - выступать в качестве регистратора в подобных случаях.
Итак, сначала создаем новый документ «ОперацияБух», в качестве его даты прописываем, например, текущую дату, записываем данный документ в базу данных. Далее создаем объект набор записей по нужному нам регистру. Устанавливаем отбор по созданному регистратору. После этого добавляем новую запись к набору записей и заполняем ее поля данными. По окончании цикла выполняем запись сформированного набора записей.
Как получить остаток по счету?
Получим остатки по счету «Товары на складах» в разрезе организаций и товаров (Субконто 1). Для этой цели можно использовать следующий запрос к виртуальной таблице остатков регистра бухгалтерии «Хозрасчетный» :
Запрос = Новый Запрос;
Запрос.Текст = ”
|ВЫ БРАТЬ
I ХозрасчетныйОстатки.СубконтоІ,
I ХозрасчстныйОстатки.Организация.
I ХозрасчстныйОстатки.СуммаОстаток,
I ХозрасчстнынОстатки.КоличествоОстаток |ИЗ
I РегистрБухгалтерии.Хозрасчетный.Остатки(&Период. Счет = &Счет,.)
I КАК ХозрасчетныйОстатки": '
Запрос.УстановитьПараметрС'Нериод", КонецДня(ДатаОтчета));
Запрос. УстановнтьПараметрС’Счет”,
ПланыСчетов.Хозрасчетный ТоварыНаСкладах): РезультатЗапроса = Запрос. ВыполнитьО;
В качестве параметров запроса устанавливаются необходимый счет («ТоварыНаСкладах») и дата, на которую надо получить остатки.
Как получить обороты по счету?
Получим обороты по счету «Товары на складах» за указанный интервал дат (переменные «НачПериода» и «КонПериода»).
Для этой цели можно использовать следующий запрос к виртуальной таблице оборотов регистра бухгалтерии «Хозрасчетный» :
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ I ХозрасчетныйОбороты.СуммаОборотДт,
I ХозрасчетныйОбороты.С?ммаОборотКт |ИЗ
I РегистрБухгалтерии.Хозрасчетный.Обороты(&НачПериода, &КонІ1ериода,
Период, Счет = &Счет,,,,)
I КАК ХозрасчетныйОбороты";
Запрос.УстановитьПараметрС'НачПериода", НачПериода); Запрос.УстановитьПараметр( "КонПериода". КонПериода);
Запрос. УстановитьПараметрС'Счст",
ПланыСчетов.Хозрасчетный.ТоварыНаСкладах);
РезультатЗапроса = Запрос. Выполнить));
В качестве параметров запроса устанавливаются необходимый счет («ТоварыНаСкладах») и даты начала и конца периода, за который нужно получить обороты.
Как получить остатки по счетам?
Необходимо получить данные о валютных активах компании в разрезе счетов и валют.
Для решения задачи можно использовать следующий текст запроса:
"ВЫБРАТЬ
I ХозрасчстныйОстатки.Счет.
I ПРЕДСТАВЛЕНИЕ(ХоэрасчетныйОстатки.Счет),
I ХозрасчетныйОстатки.ВалютнаяСуммаОстатокДт КАК ВалютнаяСуммаОстатокДт,
I ХозрасчетныйОстатки.Счет.Порядок КАК СчетПорядок. I ХозрасчетныйОстатки.Валюта КАК Валюта.
I ПРЕДСТАВЛЕНИЕ(ХозрасчетныйОстатки.Валюта)
|ИЗ
I РегистрБухгалтерии.Хозрасчетный.Остатки(&Дата.
Счет.Валютный И Счет.Вид = &Активный..)
КАК ХозрасчетнынОстатки
ІУПОРЯДОЧИТЬ ПО I СчетПорядок
Іитоги
I СУММА(ВалютнаяСуммаОстатокДт)
|ПО
I Валюта";
Необходимо определить следующие параметры:
Запрос.УстановнтьПарамстрГ’Активный", ВидСчета.Активный): Запрос.УстановнтьПарамстрСДата". Дата);
Фактически идет обращения к дебетовым остаткам счетов являющихся активными и по которым ведется валютный учет.
Как перенести остаток со счета на счет?
Необходимо реализовать механизм, позволяющий списать дебиторскую задолженность по указанному контрагенту и договору взаиморасчетов с ним.
Запрос = Новый Запрос:
Запрос.Текст = "ВЫБРАТЬ I ХозрасчетныйОстатки.СуммаОстатокДт |ИЗ
I РегистрБухгалтерии.Хозрасчетный.Остатки(&Период,
Счет = &Счст.,
Субконто I = &Контрагент И Организация = &Организация И Субконто2 = &Договор)
I КАК ХозрасчетныйОстатки";
//Считаем что на счете ведется аналитика только в разрезе контрагентов // и договоров.
Запрос.УстановитьПараметрС'Период", Период 1);
Запрос.УстановитьПараметрС'Контрагент", Контрагент); Запрос.УстановитьПараметрС'Договор", Договор); Запрос.УстановитьПараметрС'Организация". Организация); Запрос.УстановнтьПараметрС'Счет".
ПланыСчетов.Хозрасчетный РасчетыСПокупателями):
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.СледуюшийО Тогда Документ = Документы.ОнерашіяБух.СоздатьДокумснтО:
Документ.Дата = РабочаяДата;
Документ.Организацня = Организация:
Документ.Содержание = "Погашение дебиторской задолженности";
Проводка = Документ.Движения.Хозрасчетный.ДобавитьО; Проводка.СчетДт = ПланыСчетов.Хозраечетный.РасчетыСПокупателями; Проводка.СчетКт = ПланыСчетов.Хозрасчетный.ПрочиеРасходы; Проводка.СубконтоДт.Контрагенты = Контрагент; Проводка.СубконтоДт.Договоры = Договор;
Ироводка.Сумма = Выборка.СуммаОстатокДт;
Документ.СуммаОперации = Выборка.СуммаОстатокДт;
Форма = Документ.ПолучитьФормуч):
Форма.ОткрытьО;
КонецЕсли:
В обработке используется документ «ОперацияБух» являющийся по смыслу ручной операцией. С его помощью можно сформировать любую проводку.
Как найти первый документ, приведший к появлению кредитового остатка на счете?
Применение виртуальной таблицы «ОстаткиИ Обороты» с соответствующим заполнением параметра «Периодичность» позволяет решить задачу:
ВЫБРАТЬ ПЕРВЫЕ 1
ХозрасчетныйОстаткиИОбороты.Регистратор КАК Регистратор ИЗ
РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&ДатаН.
&ДатаК. Регистратор,, Счет = &Счет,,)
КАК ХозрасчетныйОсіаткнИОбороты
ГДЕ
ХозрасчстныйОстаткиИОбороты.СуммаКонечныйОстатокКт > О УПОРЯДОЧИТЬ ПО ХозрасчегныйОстаткиИОбороты.Период,
Регистратор
таблицу
за
Используем виртуальную
«РегистрБухгалтерии.Хозрасчетный. ОстаткиИ Обороты»
определяемый пользователем период (ДатаН и ДатаК), с периодичностью по регистратору и отбором по указанному счету.
Накладываем условие - кредитовый остаток счета больше нуля.
Упорядочиваем результат по периоду, затем по регистратору. Это важно потому, что по умолчанию таблица упорядочена не будет. Кроме того, обратите внимание - первичен в упорядочивании период, и только при совпадении периодов дальнейшее упорядочивание идет по регистратору.
Посредством ключевых слов ВЫБРАТЬ ПЕРВЫЕ 1 обеспечиваем, чтобы в результат запроса попала только первая запись.
Как выбрать все счета, в аналитике которых присутствуют либо вид субконто «Контрагент», либо вид субконто «Договор»?
Данную задачу можно решить посредством запроса:
ВЫБРАТЬ
Хозрасчет ныйВндыСубконто.Ссылка как Счет ИЗ
ПланСчетов. Хозрасчетный. ВидыСубконто КАК ХозрасчетныйВидыСубконто ГДЕ
ХозрасчетныйВидыСубконто.ВидСубконто.Наименование
В ("Договоры". "Контрагенты")
Источник - таблица «ВидыСубконто» требуемого плана счетов (в нашем случае «Хозрасчетный»). Выходным полем делаем поле «Ссылка», присутствующее в записях этой таблицы. Накладываем условие отбора на вхождение в список, состоящий из наименований нужных нам видов субконто. В результате получаем счета.
Как выбрать все счета, в аналитике которых присутствуют как вид субконто «Контрагент», так и вид субконто «Номенклатура»?
Данную задачу можно решить посредством запроса:
ВЫБРАТЬ
ХозрасчсгныйВидыСубконто.Ссылка КАК Счет ИЗ
ПланСчетов. Хозрасчетный. ВидыСубконто КАК ХотрасчетныГіВидыСубконто ВНУТРЕННЕЕ СОЕДИНЕНИЕ
ПланСчетов.Хозрасчетный.ВидыСубконто КАК ХозрасчетныйВндыСубконтоІ ПО
ХозрасчетныйВндыСубконто.Ссылка = ХозрасчетныйВндыСубконтоІ .Ссылка
ГДЕ
(ХозрасчетнынВидыСубконто.ВидСубконто. Наименование = "Контрагенты")
И
(ХозрасчетныйВндыСубконтоІ .ВидСубконто.Наименование = "Номенклатура")
Выполняем внутреннее соединение двух таблиц «ВидыСубконто» плана счетов «Хозрасчетный» по равенству полей «Ссылка». Посредством отбора в запросе останутся только те записи, у которых поле «Наименование» вида субконто первой таблицы равно «Контрагенты», а второй - «Номенклатура». Выходное поле - «Ссылка». Это ссылки на нужные счета.
Как добавить новый вид субконто к счету?
Необходимо к счету с кодом «90.01.1» плана счетов «Хозрасчетный» добавить новый оборотный вид субконто «Менеджеры»: тип значения -«СправочникСсылка.Пользователи», признак - «Суммовой».
Обычно такая задача решается интерактивными средствами в режиме «1С:Предприяте» или, если счет предопределенный, можно так же в режиме «Конфигуратор».
В любом случае сначала надо убедиться, что в состав свойства Тип значения характеристик плана видов характеристик,
предназначенного для хранения видов субконто, входит справочник « Пользователи»:

Если же это необходимо все же выполнить именно в обработке, можно сделать и так:
|
ВидМенеджеры = ПланыВидовХарактеристик |
|
|
ВндыСубконтоХозрасчетныс |
|
|
.НайтнПоНаименованикИ "Менеджеры", |
Истина): |
|
// Добавить новый вид характеристик. |
|
|
Если ВидМенеджеры.ПустаяО Тогда |
|
|
ВидМенеджеры = ПланыВидовХарактеристик |
|
|
.ВидыСубконтоХозрасчетные |
|
|
.СоздатьЭлементІ): |
|
|
ВидМенеджеры.Наименование = "Менеджеры": |
|
|
ВндМенеджеры.ТипЗначения = |
|
|
Новый ОпнсаннеТиповС’СправочннкСсылка.Пользователи”); |
|
ВидМенеджеры.ЗаписатьО; |
|
|
КонецЕсли; |
|
|
// Получить нужный счет. |
|
|
Счет = ПланыСчетов.Хозрасчстный.НайтиПоКоду("90.()1. |
Г): |
|
Если (Не Счет.ПустаяО) И |
|
|
(Счет.ВндыСубконто.Найти(ВидМенеджеры) = Неопределено) Тогда |
|
// Добавить новый вид субконто к счету. * |
|
|
ОбъектСчета = Счет.ПолучитьОбъектО; |
|
|
НовыйВидСубконто = ОбъекгСчета.ВндыСубконто.ДобавитьО: |
|
НовынВидСубконто.ВидСубконто = ВидМенеджеры; |
|
|
НовыйВидСубконто.ТолькоОбороты = Истина; |
|
|
НовыйВидСубконто.Суммовой = Истина; |
|
|
ОбъектСчета. ЗапнсатьО; |
|
|
КонецЕсли; |
|
Сначала пытаемся найти в плане видов характеристик «ВидыСубконто» данной конфигурации найти вид «Менеджеры». Причем поиск осуществляем по полному совпадению наименования.
Если такового вида не найдено - создаем новый элемент в плане видов характеристик «ВидыСубконто». Устанавливаем его наименование и тип значения. Записываем.
Далее убеждаемся, есть ли в плане счетов «Хозрасчетный» счет с указанным кодом.
Если счет есть, и среди его видов субконто нет вида, соответствующего менеджерам, - будем его модифицировать. А значит, нужно сначала получить объект данного счета.
Далее добавляем новую строку в таблицу «ВидыСубконто» данного счета, прописываем в ней вид нужный вид субконто, ставим признаки «Суммовой» и «ТолькоОбороты».
Замечание: желательно заранее проконтролировать, какое
максимальное количество уровней субконто разрешено для данного плана счетов, чтобы не получилось, что добавление нового вида субконто приведет к превышению этого порога.
Как из регистра бухгалтерии «Хозрасчетный» получить обороты только по валютным счетам?
Структура регистра следующая:
|
Щ Хозрасчет»*)* Измерения |
 |
|
tm Ресурсы |
Е|
< ВалютмаяСумма J Количество
|
В s Реквизиты |
 |
Чтобы получить такую таблицу:
|
Организация |
Счет |
Валю
та |
СуммаОб
оротДт |
Валютна яСуммаО борот Дт |
СуммаОб
оротКт |
Валютна
яСумма
ОборотК
т |
|
МебельСт |
52 |
USD |
7596,16 |
260,00 |
|
|
|
МебельСт |
60.31 |
USD |
|
|
7697,23 |
265,00 |
|
МебельСт |
62.21 |
USD |
7596,16 |
260,00 |
7596,16 |
260,00 |
|
МебельСт |
62.31 |
USD |
65270,12 |
2269,75 |
56716,86 |
1969,75 |
|
МебельСт |
62.32 |
USD |
2879,10 |
100,00 |
9163,24 |
318,21 |
|
Нева ТД |
60.21 |
руб. |
|
|
59,00 |
59,00 |
|
Нева ТД |
60.31 |
USD |
63000,00 |
2187,96 |
82231,81 |
2847,00 |
|
Нева ТД |
60.31 |
EUR |
4463,78 |
122,30 |
4463,78 |
122,30 |
|
Нева ТД |
60.32 |
USD |
50000,00 |
1736,46 |
50000,00 |
1736,46 |
|
Нева ТД |
60.32 |
EUR |
560,11 |
15,69 |
|
|
|
Нева ТД |
62.31 |
USD |
3239,85 |
110,00 |
2500,00 |
84,77 |
|
Нева ТД |
76.35 |
USD |
|
|
142,25 |
5,00 |
|
Нева ТД |
76.39 |
USD |
|
|
2503,24 |
85,00 |
Можно воспользоваться запросом со следующим текстом:
ВЫБРАТЬ
ХозрасчетныйОбороты.Организацня КАК Организация, ХозрасчстныйОбороты.Счет КАК Счет. ХозрасчетныйОбороты. Валюта, ХозрасчстныйОбороты.СуммаОборотДт, ХозрасчетныйОбороты.Вал ютнаяСуммаОборотДт. ХозрасчетныйОбороты.СуммаОборотКт, ХозрасчетныйОбороты. ВалютнаяСуммаОборотКт ИЗ
РегистрЬухгалтерни.Хозрасчетный.Обороты(&ДатаНач.
&ДатаКон,. Счет.Валютный,.
КАК ХозрасчетныйОбороты
УПОРЯДОЧИТЬ ПО Организация,
ХозрасчетныйОбороты.Счет. Код
Источником является виртуальная таблица
«РешстрБухгалтерии.Хозрасчетный.Обороты» с установленными отборами по интервалу дат и признаку счета.
В качестве выходных полей указываем счета, значения измерений, дебетовый и кредитовый обороты ресурсов «Сумма» и « ВалютнаяСумма».
Полученную таблицу упорядочиваем по значению поля «Организация» и возрастанию кодов счетов.
Как выбрать в регистре бухгалтерии «Хозрасчетный» обороты по «60-ым» счетам, исключив внутренние обороты между ними?
Взаимными оборотами в данном случае могут являться случаи зачета авансов, уплаченных поставщику.
Решение данной задачи можно построить посредством запроса:
ВЫБРАТЬ
ХотрасчетныйОбороты.Счет,
Хо зрасче і ныйОбороты.СуммаОборотДт, ХозрасчетныйОбороты.СуммаОборотКт
т
РегистрБухгалтсрии.Хозрасчетный.Обороты(&ДатаНач,
&ДатаКон ,,
Счет В ИЕРАРХИИ (&Счет),,, НЕ(КорСчет В ИЕРАРХИИ (&Счет)). ) КАК ХотрасчетныйОбороты
УПОРЯДОЧИТЬ ПО ХозрасчетныйОбороты.Счет.Код
Источником будет виртуальная таблица
«РегистрБухгалтерии.Хозрасчетный.Обороты», с установленными отборами по интервалу формирования, по счету и по корсчету.
Условием по счету ставим вхождение в иерархию параметра запроса «Счет» (в него потом передадим ссылку на 60-ый счет).
Условием по корсчету ставим НЕ вхождение в иерархию параметра запроса «Счет».
Как реализовать метод «красного сторно» для регистра бухгалтерии?
Иногда требуется отменить в текущем отчетном периоде операцию, сделанную в прошлом отчетном периоде. Как этого добиться в отношении регистра бухгалтерии «Хозрасчетный»?
Для этого можно создать документ «Сторно». В его составе будет реквизит «СторнируемыйДокумент» (тип значения «ДокументСсылка»).
Далее, например, при проведении документа «Сторно», делаем выборку записей, связанных со сторнируемым документом и формируем на их основе сторнирующие записи:
Процедура ОбработкаПроведсния(Отказ, Режим)
СторнируемыеДвижсния = РегистрыБухгалтерии .Хозрасчетный
-ВыбратьПоРегистратору(СторнируемыйДокумент); Пока СторнируемыеДвнження.СледующийО Цикл
Проводка = Движення.Хозрасчетный.ДобавитьО:
Проводка.Период = Дата:
Проводка.СчетДт = СторннруемыеДвижения.СчетДт;
Проводка.СчетКт = СторнируемыеДвижения.СчетКт;
Для каждого Субконто Из СторнируемыеДвижения.СубконтоДт Цикл Г1роводка.СубконтоДт[Субконто.Ключ] = Субконто.Значение;
КонецЦикла;
Для каждого Субконто Из СторнируемыеДвиження.СубконтоКт Цикл I Іро волка.СубконтоКт[Субконто. Ключ] = Субконто.Значение;
КонецЦикла:
Проводка.ВалютаДт = СторнируемыеДвнжения.ВалкгпіДт;
Проводка. Вал ютаКт = СторнируемыеДвижения.ВалютаКт:
Проводка.ВалютнаяСуммаДт = - СторнируемыеДвижения.ВалютнаяСуммаДт: Проводка.Вал ютнаяСуммаКт = - СторнируемыеДвижения.ВалютнаяСуммаКт; Проводка.КолнчествоДт = - СторнируемыеДвнжения.КоличествоДт; Проводка.КолнчествоКт = - СторнируемыеДвижсния.КолнчествоКт; Проводка. НомерЖурнала = СторнируемыеДвижсния. НомерЖурнала; Проводка.Организация = СторнируемыеДвиження. Организация: Проводка.Содержание = СторнируемыеДвижения.Содержание; Проводка.Сумма = - СторннруемыеДвижения.Сумма;
КонецЦикла;
Движения.Хозрасчетный.Записать();
КонеиПроцедуры
Посредством метода «ВыбратьПоРегистратору» выбираем движения документа «СторнируемыйДокумент» по регистру бухгалтерии «Хозрасчетный».
В цикле перебор этой выборки - формируем новые записи в регистре посредством свойства «Движения» данного документа.
Поле «Период» в них заполняем значением даты нашего документа. Остальные поля записей заполняем содержимым полей сторнируемых движений. Обратите внимание на два цикла перебора субконто дебета и кредита.
Для числовых значений ресурсов при заполнении проставляем знак
«~».
После того, как в цикле будет создан весь набор записей документа -записываем набор записей непосредственно в регистр.
Сложные периодические расчеты
ф Как получить сумму начисления по конкретному видурасчета указанному сотрудникув указанном периоде?
Получим из регистра расчета «БУОсновныеНачисления» результат начисления (ресурс регистра расчета «Результат») некоторому сотруднику («ФизЛицо») по некоторому виду расчета («ВидРасчета») в указанном периоде («Период!»):
Запрос = Новый Запрос;
Заирос.Текст = "ВЫБРАТЬ I БУОсновныеНачисления.Результат |ИЗ
I РегистрРасчета.БУОсновныеНачисления КАК БУОсновныеНачисления |ГДЕ
I БУОсновныеНачнсления.ГІериодРегистрации = &Г1ериод
I И
I БУОсновныеНачисления.ФизЛицо = &ФизЛицо I И
I БУОсновныеНачисления.ВидРасчета - &ВидРасчета";_
Значение параметров запроса берется из соответствующих переменных, существующих в контексте модуля.
Запрос.УстановитьПараметрІ "Период", НачалоМесяца(Период1)); Запрос.УстановитьПараметрС'ВидРасчета", ВидРасчета); Запрос.УстановитьПараметрС'ФизЛицо", ФизЛицо);
(D Как получить сумму всех начислений указанному сотруднику в указанном периоде?
Будем считать, что в конфигурации при решения задач расчета заработной платы для начислений определено два регистра расчета и два плана видов расчета (по основным начислениям и по дополнительным), учет ведется только для одной организации. Необходимо получить данные по всем начислениям сотрудника.
Для решения данной задачи можно использовать текст запроса:
"ВЫБРАТЬ
I БУОсновныеНачисления.Организация КАК Организация,
I ПРЕДСТАВЛЕНИЕ(БУОсновныеНачнслення.Организация),
I БУОсновныеНачисления. ВидРасчета,
I ПРЕДСТАВЛЕНИЕ) БУОсновныеНачисления. ВидРасчета),
I БУОсновныеНачисления.Результат КАК Результат,
I ""’Основные"" КАК ВариантНачислений |ИЗ
I РегистрРасчета.БУОсновныеНачнсления КАК БУОсновныеНачисления |ГДЕ
I БУОсновныеНачисления.ПсриодРегистрации = &НужныйПернод I И БУОсновныеНачисления.ФизЛицо = &ФнзЛнцо
[ОБЪЕДИНИТЬ ВСЕ
ІВЫБРАТЬ
I БУДополнителыіыеНачисления.Органнзация,
I ПРЕДСТАВЛЕН И Е(БУДополнительныеНачисления.Организация),
I БУДополнителыіыеНачисления.ВидРасчета.
I ПРЕДСТАВЛЕНИЕ) БУДополнитсльныеНачисления.ВидРасчета),
I БУДополнительныеНачислення.Результат.
I ""Дополнительные""'
|ИЗ
I РегистрРасчета.БУДополнителыіыеНачисления I КАК БУДополнительныеНачислення |ГДЕ
I БУДополнительныеНачисления.ПсриодРегистрации = &НужныйПсриод
I И
I БУДополнительныеНачисления.ФизЛицо = &ФизЛицо |ИТОГИ СУММА(Результат)
|ПО ОБЩИЕ, Организация. ВариантНачислений";
Нужно не забыть передать значения определенным в тексте запроса параметрам.
Как получить таблицу перерасчетов по перерасчетам нескольких регистров?
По данным перерасчета «ПерерасчетОсновныхНачислений» регистра «ОсновныеНачисленияРаботниковОрганизации» и перерасчета « ПерерасчетД ополнительныхНачисл ений» регистра
«ДополнительныеНачисленияРаботниковОрганизации» необходимо
получить таблицу вида:
|
Работник |
Вид Расчета |
Документ |
|
|
|
|
|
|
|
|
|
|
|
|
В обоих перерасчетах присутствует измерение «ФизЛицо».
Задачу можно решить посредством объединения запросов по таблицам перерасчетов регистров:
ВЫБРАТЬ
ПерсрасчетОсновных.ФизЛицо КАК Работник, ПсрсрасчетОсновных.ВидРасчета,
ПерерасчстОсновных.Объект Перерасчета КАК Документ ИЗ
РегистрРасчета
.ОсновныеНачисленияРаботниковОрганизации .ПерерасчетОсновныхНачислений КАК ПерерасчетОсновных
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Перерасчет Дополнительных.ФизЛицо, ПсрерасчетДополнительных.ВидРасчста, ПерерасчетДополннтсльных.ОбъектПерерасчета ИЗ
РегистрРасчета
•ДополнительныеНачисленияРаботниковОріанизаиии .Перерасчет Дополнительных Начислений КАК ПерерасчетДополнительных
Как для документа «НачислениеЗарплатыРаботникам» определить номера строк записей полностью вытесненных видов расчета?
При работе с множественным вытеснением видов расчета может оказаться ситуация что запись документа по регистру расчета содержит полностью вытесненный вид расчета. Например, человек весь месяц проболел -вид расчета «оклад» полностью вытесняется видом расчета «Больничный».
Поиск таких записей можно выполнить посредством следующего запроса:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
УправленческиеНачисления.НомерСтроки КАК НомерСтроки ИЗ
РегистрРасчета.УправленческисНачисления КАК УправленческиеНачисления ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета .У правленческиеНачисления
.ФактическийПернолДействня(Регистратор = &парамСсылка)
КАК УправленческиеНачисленияФактичсскийПериодДействия ПО
У правленческиеНачисления.НомерСтроки =
У правленческиеНачнслеиияФактическнйПериодДействия. НомерСтроки И
УправленческиеНачислсния. Регистратор =
У правленческиеНачисленияФактическийІІериодДействия.Регистратор
ГДЕ
УправленческиеНачисления.Регистратор = &парамСсылка И
((У правленчсскисНачислснняФакгическийІІериодДействия. Регистратор)
ЕСТЬ NULL)
В запросе выполняется левое внешнее соединение таблицы регистра «УправленческиеНачисления» и виртуальной таблицы
«УправленческиеНачисления.ФактическийПериодДействия».
В параметрах виртуальной таблицы и в условиях запроса указан отбор по данному документу. Соединение строится по равенству полей «НомерСтроки» и «Регистратор».
В результате соединения могут появиться записи, у которых значение поля «Регистратор» виртуальной таблицы равно NULL. To есть для
данной записи фактический период действия отсутствует. Такие записи и есть предмет нашего поиска.
Каксформировать расчетный листок сотрудника?
Будем считать, что в конфигурации для решения задач расчета заработной платы определены два регистра расчета и два плана видов расчета (соответственно по ачислениям и удержаниям), учет ведется только для одной организации. Необходимо получить данные для расчетного листка сотрудника.
Для решения данной задачи можно использовать следующий текст запроса (его можно определить в конструкторе выходной формы):
"ВЫБРАТЬ
I ВложенныйЗанрос.ФизЛицо.
I П РЕДСТ А ВЛ ЕМ И Е( Вложен н ы й Запрос.Фи зЛ и цо),
I ВложенныйЗамрос.ФизЛицоПредставление КАК ФнзЛицоПредставлениеІ,
I ВложенныйЗапрос.ВидРасчега.
I ПРЕДСТАВЛЕНИЕ(ВложенныйЗапрос.ВидРасчета).
I ВложенныйЗанрос.ВидРасчетаПредставленис КАК ВидРасчетаПредставлениеІ.
I ВложенныйЗапрос. Результат КАК Результат,
I ВложенныйЗапрос.ТипРасчега КАК ТипРасчета |ИЗ
I (ВЫБРАТЬ
I БУОсновныеНачисления.ФизЛицо КАК ФизЛицо,
ПРЕДСТАВЛЕНИЕ(БУОсновныеНачисления.ФизЛицо)
КАК ФизЛицоПредставление,
I БУОсновныеНачисления ВидРасчета КАК ВидРасчета.
ПРЕДСТА ВЛ ЕН И Е(БУОсновныеНачислення. ВидРасчета)
К ЛК ВидРасчетаПредставление,
БУОсновныеНачисления.Результат КАК Результат,
’"'Начисления'"' КАК ТипРасчета I ИЗ
РеіистрРасчсіа. БУОсновныеНачисления КАК БУОсновныеНачисления
I ГДЕ
I БУОсновныеНачисления.ФнзЛицо = &ФизЛицо { И БУОсновныеНачисления.ПериодРепістрацин — &| ІужныйПериол
I ОБЪЕДИНИТЬ ВСЕ
I ВЫБРАТЬ
УдержанняРаботниковОріанизаций.ФизЛицо.
ПРЕДСТАВЛЕН ИЕ(УдержанияРаботниковОрганнзаиий.Фи'зЛицо), УдержанияРаботниковОрганнзаций.ВидРасчета.
ГІРЕДСТАВЛЕНИЕ(УлержанняРабогнііковОріанизаннй.ВидРасчета)._
I -У держанияРабогниковОрганизацнй. Результат.
I '"Удержания""
I ИЗ
I РегистрРасчста.УдержанияРаботннковОрі анизашш КАК УдержанияРаботниковОрганизаций
I ГДЕ
УдержанияРаботниковОрганизаций.ФизЛицо = &ФизЛицо И УдержанияРаботниковОрганизаций. ПернодРепістрации = &НужныйПериод) КАК ВложенныйЗапрос |ИТОГИ
СУММА(Результат)
|ПО
ОБЩИЕ,
I ТішРасчета";
Нужно не забыть передать значения определенным в тексте запроса параметрам и используя возможности работы с табличным документом настроить внешний вид расчетного листка сотрудника.
Как организовать сторнирование уже произведенных расчетов прошлых периодов?
Классическим примером является ввод январского больничного в феврале или т.п.
Допустим, работаем с регистром расчетов «ОсновныеНачисления»:
- 0сисвмыеНачис»іеимяРа6от»*жов0ргаимзашм
ф-JL. Иэмарамя
Еt- ФиэЛицо I. Организация t. Приказ в- f
m Ресурсы }~ I Резул»тат г -1 Отработано Дней г~ I ОтработаноЧасов !—I ОтрабогаиоДнейЛоЛягиаиевке J— I Норме Дней (-— I НормаЧасое *— | НормаДиейЛоПятионееке 0 s Реквизиты
- Графит. Работы - ВиаУчетаВреме*м - Размер
- Допо«**пельныеДатыые - ПойразделемиеОрганиззции - ПериоаРасчетаСреанегоЗаработкаНачало - ПериоаРасчетаСреанегоЗаработкаОгончатме *—» ДагтаНачалаСобыгия
Получить данные тех записей регистра, с которыми конкурируют текущие записи набора записей регистра, выполненные данным регистратором, можно при помощи метода ПолучитьДополнение() менеджера регистра:
|
ТаблмцаСторноЗаписей = Движения |
|
|
.Основн ыеі Іач мелен ня Работни .ПолучнтьДополнснисІ); |
овОрганизации |
|
Для каждого СтрокаСторно Из ТаблмцаСторноЗаписей Цикл |
// Добавить сторно-записи в набор записей регистра.
// Новая запись движений. |
|
|
Движение = Движения. ОсновнысНачислснияРаботникояОргани зации Добавить!); |
|
// Заполнить свойства. |
|
Движение. ПериодРегнстрации = Строка. ПериодРсгистрацинСторно:
Движение. ПериодДействия Начало = Строка. ПериодДействия НачалоСторно; Движение.ПериодДействия Конец = Строка. ПериодДеііствияКонсцСторно; |
|
Движение.БазовыйПсриодНачало = Строка.БазовыйПі |
•риодНачало: |
|
Движение. БазовыйПериодКонец = Строка. БазовыйГІериодКонец; |
Движение. ВидРасчета = Сгрока.ВидРасчеі
Движение.Сторно = Истина; |
а; |
// Заполнить измерения.
Движение.ФизЛицо = Строка.ФизЛицо;
Движение.ГІриказ = Строка. Приказ;
Движение.Организация = Строка.Организация; |
|
|
// Ресурсы не заполнять, потому что здесь не происходит // только подготовка новой записи |
расчет. |
|
// Заполнить реквизиты. |
|
|
Движенне.ГрафнкРаботы = Строка. ГрафикРаботы: Движение.Размер = Строка.Размер; |
|
Движение. ВидУ четаВремени = Строка. ВидУчетаВремени;
Движение.ПодразделеннсОрганизацин = Строка.ПодразделениеОрганизации: |
|
Движение. ПериодРасчетаСреднегоЗаработкаНачало = |
|
|
Сзрока.ПериодРасчетаСреднегоЗаработкаНачало; |
|
Движение. ІІериодРасчетаСреднегоЗаработкаОкончаниі |
= |
|
Строка.ПериодРасчетаСрсднегоЗаработкаОкончание; |
КонецЦнкла;
Движения.ОсновныеНачисленияРаботниковОрганизацт |
.Записать!); |
Посредством свойства «Движения» документа обращаемся к набору записей этого документа по регистру расчета «ОсновныеНачисления». Применяем к этому набору записей метод ПолучитьДополнение().
Результатом будет таблица значений, содержащая данные конкурирующих расчетов.
Для того, чтобы записи нашего документа могли записаться несмотря на то, что период действия уже "занят" ранее зарегистрированными записями, выполняем цикл перебора строк полученной таблицы значений, вводя соответствующие им сторно-записи.
В каждой новой записи в поле «ПериодРегистрации» пропишем значение из поля «ПериодРегистрацииСторно» таблицы дополнения. В поле «ПериодДействияНачало» - «ПериодДействияНачалоСторно», в поле «ПериодДействияКонец» - «ПериодДействияКонецСторно». Далее устанавливаем значение Истина для поля «Сторно». Значения для остальных полей новой записи, кроме ресурсов, один в один переносим из полей таблицы «ТаблицаСторноЗаписей».
Ресурсы не заполняем потому, что таблица дополнения содержит не готовые данные для сторно-записи, а лишь данные для расчета сторно-записи (на основании того, что расчет ресурсов еще будет выполняться).
После того, как цикл завершается, выполняем запись новых записей в регистр.
Потом можно приступать к их расчету.
Бизнес-процессы
Как определить бизнес процесс, в котором количество последовательных этапов определяется индивидуально на момент старта экземпляра процесса?
Требуется реализовать следующий процесс:
Каждый день необходимо «объезжать» склады компании. С утра становится известным состав вышедших на работу водителей. Далее менеджеры компании определяет маршрут движения каждого водителя (точек маршрута может быть произвольное количество). Диспетчерская служба отслеживает, на какой точке маршрута находится каждый водитель. После отработки маршрута водитель должен сдать путевой лист с отметками о показаниях спидометра и расходе горючего заранее определенному сотруднику компании. Только после этого процесс считается завершенным.
Для реализации задачи создаем задачу «ЭтапыПути».
Реквизиты адресации:
• Пользователь (Ссылка на справочник «Пользователи»);
• Подразделение.
Считается что в регистре сведений, отвечающем за адресацию соответствующие сведения измерения существуют.
Реквизиты задачи:
• ДатаВыполнения (Время выполнения задачи);
• Исполнитель (Ссылка на справочник пользователей системы);
• Склад (ссылка на справочник складов).
В модуле объекта необходимо разместить процедуру - обработчик
события Перед выполнением:
Процедура ПередВыполиением(Отказ)
Если Исполнитель.ПустаяО Тогда Исполнитель = ПарамстрыСеанса.ТекущийИсполнитсль: КонецЕсли;
ДатаВыполнения=ТекущаяДата();
КонецПроцедуры
Перед выполнением задачи в нее будут записываться информация о пользователе системы выполняющем задачу и дате со временем ее выполнения.
Далее необходимо определить бизнес процесс «НаМаршруте». В свойство «Задачи» выбрать «ЭтапПути». Реквизиты бизнес процесса:
• Водитель (ссылка на соответствующий справочник)
• ПоказанияСпидометраНачальные (Число)
• ПоказанияСпидометраКонечные (Число)
• РасходТоплива (Число)
Карта маршрута бизнес процесса:
Как, не открывая форму внешней обработки, выполнить ее процедуру
У точки «Определение маршрута» в группе свойств «Адресация» выбрано подразделение «Менеджеры». Для этого соответствующий элемент должен быть заведен как предопределенный.
Определен обработчик события Обработка интерактивной
активации:
ПолучитьФорму("Маршрут").Открыть(); СтандартнаяОбработка = Ложь;
При попытке открыть задачу, соответствующую данной точке будет открываться форма бизнес процесса «Маршрут». В этой форме можно отображать данные по водителю и по маршруту (с возможностью корректировки табличной части, содержащей маршрут).
Определен обработчик события При выполнении:
Если ТочкиМаршрута.КоличествоО = 0 Тогда Сообщить("Не определен маршрут!!!”); Отказ = Истина;
КонецЕсли;
В данном обработчике проверяется, что хотя бы одна точка маршрута указана, в противном случае выполнить задачу не получится.
У точки условия определен обработчик события Проверка УСЛОВИЯ:
Результат = ПолучитьТочкуМаршрута().Пустая<)
Используется функция:
Функция ПолучитьТочкуМаршрутаО
Запрос=Новый Запрос;
Запрос.Текст= "ВЫБРАТЬ ПЕРВЫЕ I
I НаМаршрутеТочкиМаршрута.НомерСтроки КАК НомерСтроки.
I НаМаршрутеТочкиМаршруга.Склад |ИЗ
I БнзнесПроцесс.НаМаршруте.ТочкиМаршрута КАК НаМаршрутеТочкиМаршруза
|ГДЕ
I (НаМаршрутеТочкиМаршрута.Склад НЕ В
(ВЫБРАТЬ РАЗЛИЧНЫЕ ЭтапПути.Склад ИЗ
Задача.УгапПутн КАК УтапПути ГДЕ
УтапПути.БизнесПроцесс = &БизнесПроцесс ))
I И
I (Ссылка = &БизнесПроцесс)
ІУПОРЯДОЧИТЬ ПО I НомерСтроки";
Запрос.УстановитьПараметрС’БизнесПроцесс". Ссылка);
Выборка = Запрос.ВыполнитьО.ВыбратьО;
Если Выборка.СледующийО Тогда Возврат (Выборка.Склад);
Иначе
Возврат(Справочники.Склады. ПустаяСсылкаО);
КонеиЕсли;
КонецФункции
Данная функция возвращает следующую точку маршрута или пустую ссылку, в случае если весь маршрут пройден.
У точки «Точка маршрута» в свойстве «Подразделение» группы свойств «Адресация» выбрано «Диспетчерская» (предопределенный элемент справочника «Подразделения»).
Определен обработчик события При СОВДЭНИИ задач:
ФормируемыеЗадачн[0].Склад = ПолучитьТочкуМаршрута():
В этом обработчике для задачи устанавливается текущий склад (в соответствии с ранее определенным маршрутом). «Формируемые задачи» это параметр, принимаемый данным обработчиком события.
У точки «Путевой лист сдан» в свойстве «Пользователь» группы свойств «Адресация» выбрано «Контролеров» (предопределенный элемент справочника «Пользователи»). Можно отказаться от подобного способа назначения ответственного за выполнение задачи. Используя обработчик события При СО0ДЭНИИ задач и данные в системе (регистре сведений, ответственном за адресацию) ответственного можно назначать программно (таким же образом как в точке «Точка маршрута» назначается очередной склад).
Определен обработчик события Обработка интерактивной
активации:
ПолучитьФормуС ПутевойЛ нет").Открытій); СтандартнаяОбработка = Ложь;
При попытке открыть задачу будет открыта форма «Путевой Л ист» бизнес процесса, в которой можно будет ввести данные о показаниях спидометра и расходе топлива.
Также определен обработчик события При выполнении:
Если ПоказанияСпидометраКонечные = О ИЛИ Ссылка.РасходТоплива = 0 Тогда СообщитьР'Не введены данные но путевому листу!");
Отказ = Истина;
КонецЕсли;
Задача не будет выполняться, если не введены конечные показания спидометра и расход топлива.
Как при работе с бизнес процессами отказаться от стандартного способа формирования задачи и сформировать ее программно?
Для получения разрешения на какое-либо действие требуется получить согласование у нескольких сотрудников. Заранее не известно их количество. Согласование должно производиться параллельно, а не по схеме: сначала первый, после первого второй и т.п.
Считаем, что сотрудники, с которыми необходимо произвести согласование определяются в табличной части бизнес процесса « НаСогласование».
Карта маршрута бизнес процесса следующая:

Для того чтобы после выполнения задачи «Определение рецензентов» сформировалось столько задач, сколько рецензентов выполнено определим обработчик события Перед созданием Задач точки действия «Согласование». Текст процедуры следующий:
|
Для Каждого Рецензент Из НаСогласование Цикл |
|
Новая Задача = Задачи.ЭтапІІутн.СоздатьЗадачуО;
Новая Задача. БизнесПроцесс = Ссылка;
Новая Задача. Пользователь = Рецензент. Рецензент; |
|
|
НоваяЗадача.Наименование = "Согласование со епецнатнетом"; |
|
НоваяЗадача.ТочкаМаршрута = БизнесПроцессы |
|
|
.НаПараллельноеСогласов |
ІНИС |
|
.'ГочкиМаршрута.Соі .тасование: |
Новая Задача. Дата = ТекущаяДата();
НоваяЗадача.Записать(); |
|
ФормируемыеЗадачи.Добавить(НоваяЗадача);
КонецЦикла; |
|
|
СтандартнаяОбработка = Ложь: |
|
«Формируемые задачи» это массив, является параметром обработчика события. В нем содержаться значения имеющие тип
ЗадачаОбъект.ЭтапПути.
Если в параметр обработчика события Стандартная обработка не записать значение Ложь, то формируемый список задач будет очищен и будет создан заново исходя стандартной модели поведения.
Прочие прикладные объекты ф Как, не открывая форму внешней обработки, выполнить ее процедуру для определенного объекта?
Имеем ссылку на документ в переменной «Ссылка».
Переменная «ИмяФайла» содержит имя файла внешней обработки предназначенной для печати документа по специальной форме. Процедура «Печать» находится в модуле объекта обработки. Необходимо вызвать ее выполнение для нашего документа.
Перед выполнением данной операции необходимо проконтролировать наличие указания ключевого слова Экспорт в заголовке процедуры «Печать» модуля объекта обработки и принятие ссылки на печатаемый документ. Поскольку формы обработки задействованы не будут - ссылка будет передаваться посредством параметра процедуры.
Теперь можно сделать следующее:
Обработка = ВнешниеОбработки.Создать( ИмяФайла) Обработка.Печать(Ссылка);
Обратите внимание на то, что имя файла внешней обработки должно быть полным.
ф Как быстро получить информацию, по всем объектам, находящимся в компетенции конкретного менеджера (элемент справочника «Пользователи») по продажам?
Если вопрос скорости в данном случае критичен - лучше использовать критерии отбора.
Создаем новый критерий отбора «КомпетенцияМенеджераПродаж».
В данных нового критерия отбора указываем тип « СправочникСсылка. Пользователи».
Далее заполняем «Состав», указывая все объекты, которые должны попасть в отбор:
t| Критерий отборе КомпетснцмяМемеджер.іПродлж _ П X
Основные
Входящие
обьегтьг
фитермі
Да»еіые
состав
т*ормы
Подсистемы
Праве
Интерфейсы |
 |
Это могут быть реквизиты элементов справочников, документов и т.д. Чтобы впоследствии получить все объекты, указанные в составе и заполненные конкретным значением менеджера можно будет использовать метод Найти() критерия отбора:
МассивСсылок = КритерииОібора
.КомпетенцияМенеджераПродаж . Найти(Менеджер);
Для Каждого Ссылка из МассивСсылок Цикл Сообшить(Ссылка);
КонецЦикла;
Переменная «Менеджер», переданная в качестве параметра методу НаЙГИО должна содержать ссылку на конкретного менеджера (т.е. на элемент справочника «Пользователи»).
Результат метода - массив. Элементы массива можно перебрать стандартным способом.
Или можно использовать запрос со следующим текстом:
ВЫБРАТЬ
КомпетеншіяМенеджераПродаж.Ссылка
ИЗ
КрніеринОтбора.КомметснцияМенеджераПродаж(&Менеджер) КА К Ком потен і шя М енсджераП родаж
Параметру запроса «Менеджер» нужно будет установить значение конкретного менеджера.
Результат запроса впоследствии можно перебрать стандартной выборкой.
Формы и элементыуправления
Работа с формами
® Как открыть форму документа?
ФормаДокумента = СсылкаНаДокумент.ПолучитьФормуО: ФормаДокумента.Открыть():_
Методом ПолучитьФорму() обращаемся к основной форме документа. Если нужно обратиться не к основной, необходимо первым параметром метода указать название получаемой формы.
Далее открываем полученную форму.
Как открыть форму внешней обработки?
Имя файла внешней обработки содержится в переменной «ИмяФайла».
Тогда открытие основной формы обработки выполняется так:
Обработка = ВнешниеОбработки.ПолучнтьФорму(ИмяФаіпа); Обработка.Открыть();
Если бы требовалось открыть определенную форму этой обработки или форму с определенным ключом уникальности «Ключ» - для этого можно было бы использовать второй и третий параметры метода
ПолучитьФорму().
Например, так:
Обработка = ВнешііиеОбра6откн.ПолучитьФорму(''С:\Внсшіше\СпсцОтчет.срГ
ИмяФормы,,
Ключ);
Обработка.Открыть();_
Обратите внимание на то, что в любом случае имя файла должно быть полным.
(D Как отрыть форму отчета так, чтобы она не перекрывала собой ту форму, из которой она открыта?
Для этого форму отчета нужно открывать как подчиненную данной форме и устанавливать свойство Положен иеОкна в значение НеПерекрыватьВладельца:
Форма = Отчеты.ОтчетДиаірамма.Получи гьФормуС'ФормаОсновная". ЭтаФорма): Форма.ПоложениеОкна = ВариантПоложенияОкна. НеПерекрыватьВладельца; Форма.ОгкрытьО;
Следует учитывать, что открываемое окно будет менять свое положение, только если может полностью поместиться в пределах родительского окна, не перекрывая заданную область.
Как открыть форму отчета на весь экран?
Для этого следует воспользоваться свойством формы
СпособОтображенияОкна:
СпособОтображенияОкна = ВариантСпособаОтображенияОкна .Максимизированное;
Можно также запретить пользователю минимизировать и максимизировать открытое окно:
И чмененятьСпособОтображенияОкна = И чменениеСпособаОтображенияОкна _.Запретить;_
Следует учитывать, что использование свойства СпособОтображенияОкна возможно лишь до того, как форма начала открываться (т.е. в модуле самой формы или до выполнения метода формы Открыть(), если форма открывается «извне»).
Как из формы документа открыть форму списка данного документа, спозиционировавшись на нем же?
ФормаСписка = Документы! Метаданные!). 11 мя |. I ІолучитьФормуСііискаІ): ФормаСписка.ПараметрТекущаяСтрока = Ссылка;
ФормаСписка.ОткрытЫ);
Получаем форму списка через объект ДокументМенеджер.<ИМЯ> по имени нашего документа. Далее свойству ПараметрТбкущаяСтрока расширения формы списка документов присваиваем ссылку на наш документ. Потом открываем форму.
В данном примере форма списка будет открываться даже в том случае, если у объекта (в составе метаданных) она и не создавалась. Тогда она будет создана «налету».
Кроме того, хотелось бы обратить внимание, что по умолчанию сначала будет производиться поиск уже открытого экземпляра формы списка, и если только такового не окажется - будет открываться новый. Если же мы хотим каждый раз открывать обязательно новую форму списка (не обращая внимания на уже открытые), то лучше всего при получении формы списка генерировать для нее новый ключ уникальности.
Например, так образом ключ уникальности будет гарантировано новым:
ФормаСписка = Документы[Метаданные().Имя]
.ПолучитьФормуСписка(,, Новый УннкальныйПлентнфикаторО):
® В документе есть реквизит «Контрагент». Как открыть форму подчиненного ему справочника «ДоговорыКонтрагентов»?
Если Не Контрагснт.ПустаяО Тогда ФормаПодчиненныхДоговоров = Справочники
.ДоговорыКонтрагентов .ПолучитьФормуСписка();
ФормаПодчиненныхДоговоров.ПараметрОтборПоВладельцу = Контрагент: ФормаПодчиненныхДоговоров.ОткрытьО:
КонецЕсли:
Сначала проверяем заполнен ли реквизит «Контрагент». Если он не равен пустой ссылке получаем в переменную
«ФормаПодчиненныхДоговоров» форму списка справочника «ДоговорыКонтрагентов». По умолчанию получим основную форму, но если бы нам потребовалось получить какую-то конкретную - достаточно было бы указать имя открываемой формы первым параметром метода ПолучитьФормуСписка().
Далее устанавливаем значение «ПараметрОтборПоВлад ельцу» расширения формы списка равным ссылке на нашего контрагента и открываем форму.
© Как в форме отобразить картинку, сохраненную в реквизите справочника?
В диалоге формы (например, формы элемента справочника «Сотрудники») необходимо разместить элемент управления ПолеКартинки (его имя «Фото»). В самом справочнике существует реквизит «Фотография» имеющий тип ХранилищеЗначения (в него и записывалось значение, перед преобразованием к типу ХранилищеЗначения имевшее тип Картинка). В обработчике события При открытии формы разместим следующие строки:
|
|
|
// Значение, сохраненное в реквизите справочника, имеющеь // ХранилищеЗначения, можно только получить. Сохраненная Картинка = Фотография.Получить();
Если СохраненнаяКартинка О Неопределено Тогда // Если в хранилище было что-нибудь заранее записано... ЭлементыФормы.Фото.Картинка = СохраненнаяКартинка; КонецЕсли; |
ТИП |
Следует отметить, что если в реквизит «Фотография» может записываться не только картинка, то в этом случае обязательно необходимо производить проверку типа значения, полученного из хранилища значения.
<Х> Как в журнале документов «УчетКадров» отобрать только документы «ПриемНаРаботу»?
ь( Метаданные .Документы .ПриемНаРаботу);
ЖурналДокументовСписок.Отбор.ВидДокумента.Уетановиз
Данную работу необходимо проделать посредством основного реквизита формы журнала «ЖурналДокументовСписок».
Свойство Отбор данного объекта включает в себя свойство ВидДокумента. Необходимо только установить его значение.
Поскольку нам нужны именно документы «ПриемНаРаботу» - через метаданные получаем значение для отбора.
ф Как узнать интервал дат в открытом текущем журнале?
Интервал дат является одним из вариантов отбора для объектов типа ЖурналДокументовСписок.<имя>.
Работу необходимо вести с основным реквизитом формы журнала « ЖурналДокументовСписок»:
Если ЖурналДокументовСписок.Отбор.Дата.Использование Тогда Сообщить(ЖурналДокументовСписок.Отбор.Дата);
Иначе
Сообщить("Без ограничения [іо датам");
КонецЕсли;
Сначала проверяем, используется ли на данный момент для этого объекта отбор по свойству «Дата».
Далее можно просто получить представление элемента отбора с именем «Дата».
Как при открытии справочника сделать отбор по контрагентам, входящим в список?
Для случая, когда необходимо делать отбор по контрагентам, входящим в список значений «СписокКонтрагентов»:
Процедура ПрнОгкрытинО
СправочникСпнсок.Отбор.Ссылка.ВидСравнения = ВидС равнения. ВСписке: СправочникСписок.Огбор.Ссылка.Значение = СписокКонтрагентов; СправочникСписок.Отбор.Ссылка.Использование = Истина;
КонецПроцедуры_
Сначала устанавливаем вид сравнения для отбора по полю «Ссылка». Далее назначаем в качестве значения список контрагентов, по которым нужно осуществить отбор. Устанавливаем для свойства Использование данного элемента отбора значение Истина.
Обратите внимание, Отбор - это свойство объекта Справ0ЧНИкСпиС0К.<ИМЯ>, то есть источника данных, а не элемента управления (табличного поля).
Как обеспечить, чтобы для выбора значения покупателя в расходной накладной справочник контрагенты открывался сразу с открытой группой «Покупатели»?
Поскольку нам необходимо особым образом открыть форму выбора именно из формы документа - сначала пропишем обработчик события Начало выбора поля ввода «Контрагент» формы документа:
Процедура КонтраіентНачалоВыбора( Элемент. СтандартнаяОбработка)
Если Элемент.Значенне.Пустая() Тогда СтандартнаяОбработка = Ложь:
ФормаВыбора = Справочники .Контрагенты
.ПолучитьФормуВыбора(, Элемент); ФормаВыбора. ВыборПокупателя = Истина; ФормаВыбора.ОткрытьО;
КонецЕсли;
КонецПроцедуры
Сначала проверяем, заполнено ли значение поля ввода. Если да - то лучше ничего не делать. Стандартным поведением системы является открытие формы выбора с позиционированием на элементе, указанном в поле ввода.
Если оно не заполнено - отключаем стандартную обработку события, поскольку этим процессом будем управлять сами.
В переменную «ФормаВыбора» получаем основную форму выбора соответствующего справочника. При этом назначаем параметры:
• владелец создаваемой формы - текущий элемент управления (поле ввода «Контрагент). Впоследствии, когда выбор произойдет, система вернет выбранное значение в этот элемент (еще говорят - оповестит о выборе);
Дальше работа идет уже со справочником: находим, какая форма указана в качестве основной для выбора:

В найденной форме создаем реквизит «ВыборПокупателя», имеющий тип Булево. Затем в обработчике события При открытии необходимо добавить код, обеспечивающий установку значения свойства Текущий Родитель табличного поля «СправочникСписок».
Но сначала желательно обеспечить однозначное толкование понятия «группа Покупатели». Есть несколько вариантов:
а) Если справочник уже заполнен и группа «Покупатели» существует, можно подсмотреть код или наименование и в дальнейшем считать, что «группа Покупатели» - это элемент с таким то кодом или наименованием. Но существует опасность, что через какое-то время пользователь изменит код (наименование) этого элемента. Тогда наша процедура «потеряет» из виду «группу Покупатели». Поэтому лучше создать константу (например, «ГруппаПокупатели»), которая будет хранить ссылку на нужную группу справочника «Контрагенты».
б) Более надежным вариантом видится создание предопределенного элемента справочника с именем «Покупатели». Такому элементу «повредить» пользователю сложнее. Но тут возникнет вопрос: справочник был уже заполнен и в группе «Покупатели» 20000 элементов, как перенести их в другую группу?. Для ответа на этот вопрос в настоящем издании есть пример «Как перенести все элементы справочника «Контрагенты» из одной группы в другую?» на странице 99.
а) если идентификацию группы «Покупатели» делаем по ссылке, которая хранится в константе «ГруппаПокупатели»::
|
Если ВыборПокупателя Тогда |
|
|
ЭлементыФормы.СправочникСнисок. ИерархическийПросмотр = Истина; |
|
ЭлементыФормы.СправочникСнисок.ТекущийРодитель = |
Константы
.Г ру ппаПокупателн
.ПолучитьО; |
|
КонецЕсли; |
|
б) если идентификацию группы «Покупатели» делаем по предопределенному элементу:
Если ВыборПокупателя Тогда
ЭлементыФормы.СправочникСписок.ИерархнческийПросмотр = Истина: ЭлемснтыФормы.СправочникСписок.ТскущийРодитель = Справочники
.Контрагенты
.Покупатели;
КонсцЕсли;
Сначала проверяем значение реквизита «ВыборПокупателя» текущей формы. Если оно равно Истина - устанавливаем для соответствующего табличного поля формы свойство расширения табличного поля списка справочника ИерархическиЙПрОСМОТр, а свойство
Текущий Родитель табличного поля заполняем нужным значением.
В качестве замечания: описанное выше решение не является единственно возможным. Например, если значение текущего родителя было бы не жестко устанавливаемым («Покупатели»), а определялось в форме документа, тогда лучше для передачи информации между двумя формами воспользоваться созданием соответствующего реквизита формы выбора справочника.
Главное, чтобы Ваше решение обеспечивало возможности использования формы другими объектами независимо от ее внутреннего устройства (например, от названия элементов управления).
Табличное поле
ф Как запретить пользователю изменять порядокследования колоноквтабличном поле?
Для этого можно воспользоваться свойством табличного поля
ИзменятьПозициюКолонок:
I ЭлементыФормы.ТабличноеІ Іоле.ИзменятьПозициюКолонок - Ложь:
Если необходимо запретить перемещение только некоторых колонок, тогда следует использовать свойства ИзменятьПозицию соответствующих колонок:
ЭлементыФормы.ТабличноеПоле. Колонки. Картинка.ИзменятьПозицию = Ложь:
ЭлементыФормы.ТабличноеПоле. Колонки. Код. ИзменятьПозицию = Ложь;
ЭлементыФормы
.ТабличноеПоле
.Колонки
.Наименование
.ИзменятьПозицию = Ложь;
® Как запретить пользователю изменять любые настройки колонок табличного поля?
Для этого можно воспользоваться свойством табличного поля
ИзменятьНастройкуКолонок:
ЭлементыФормы.ТабличноеПоле.ИзменятьНастройкуКолонок= Ложь:
Если необходимо запретить перемещение только некоторых колонок, тогда следует использовать свойства ИзменятьНастроЙку нужных колонок:
ЭлементыФормы.ТабличноеПоле. Колонки. Картинка. ИзменятьНастроЙку = Ложь: ЭлементыФормы.ТабличноеПоле.Колонки.Код.ИзменятьНастройку = Ложь; ЭлементыФормы
ТабличноеПоле
Колонки
Наименование
Иімсняи.Настройку = Ложь;
ф Как вывести информацию о том, какой отбор установлен в журнале документов?
Для этого рядом с табличным полем, отображающим журнал документов, можно расположить надпись (например, с именем «НадписьОтбор»), и присвоить ей значение отбора. Система автоматически выполнит получение представления указанного отбора:
ЭлсментыФормы.НадннсьОтбор Заголовок = СписокДокумснтов.Огбор;_
Если требуется более подробная информация обо всех элементах отбора, она может быть получена, например, следующим образом:
УстановленныйОтбор = СписокДокументов.Отбор; СообщнтьС'Элементы отбора:");
Для Каждого ЭлементОтбора ит УстановленныйОтбор Цикл Сообщить(Строка(ЭлементОтбора)
+ " использование = "
+ ЭлементОтбора.Использование); КонсцЦикла;
ф Как в форме справочника установить курсор на элемент с известным наименованием?
ЭлементыФормы.СправочникСписок.ТекущаяСтрока =
Справочники
.Контрагенты
.НайтпПоНаименованмю("ПОСТАВЩИКИ", Истина):
Свойству табличного поля «СправочникСписок» Текущая Строка присваиваем значение ссылки на найденный по наименованию элемент справочника.
Причем вторым параметром метода мы установили требование искать по полному соответствию наименования.
В результате и получим требуемое.
ф Как в форме списка сделать отбор по значению реквизита?
У объекта СправочникСписок.<ИМЯ> есть свойство Отбор. В его состав входят элементы отбора. Именно работая с ними - можно решить поставленную задачу.
Если необходимо организовать отбор по единственному значению реквизита, это можно сделать так:
Сира вочникСписок.Отбор.СтавкаНДС.УстановитЫ Перечисления
.СтавкиНДС НДС 18);
Методу УСТЗШВИТЬО элемента отбора первым параметром передается значение отбора, вторым - использование. По умолчанию второй параметр имеет значение Истина.
Можно еще так:
СправочникСписок.Отбор.СтавкаНДС.Значение = Перечисления
СтавкиНДС .НДС 18:
СправочникСписок.Отбор.СтавкаНДС. ВидСравнения = ВилСравнения. Равно: СправочннкСписок.Отбор.СтавкаНДС. Использование = Истина;
Устанавливаем по одному из полей отбора нужное значение. Заполняем свойство ВидСравнения этого поля отбора значением из системного перечисления ВидСравнения (в нашем случае Равно). Указываем системе на необходимость применить фильтрацию по данному элементу отбора.
Второй способ вроде бы массивнее, но зато дает возможность применять различные виды сравнения.
ф Как запретить выдачу сообщения: «Введенные данные не отображены в списке, так как не соответствуют отбору» при добавлении новых элементов в справочник?
Для этого следует использовать свойство расширения табличного поля списка справочника ПроверкаОтображенияНовойСтроки. По умолчанию, для табличного поля, отображающего список справочника, включена проверка соответствия новой строки установленному отбору. Отключить эту проверку можно интерактивно, на закладке «Прочее» диалога настройки списка:
Настройка списка
Колонки Прочее
ОПри открытии восстанавливать позицию!
М При открытии восстанавливать колонку
В начало списка
При открытии переходить
секунд
I I Обновлять автоматически каждые
Не проверять соответствие новых строк отбору
Отмене
Применить
Справка
Или программно:
ЭлементыФормы.ПолеСииска. ПроверкаОтображенияНовойСтроки =
ВариантПроверкиОгображенияНовойСтроки
.НеПроверять;
ф Как заполнить ячейку табличного поля данными?
У табличного поля «ТабличноеПолеЗаказов» есть колонки «Заказ» (тип значения - ДокументСсылка.ЗаказПокупателя), «Контрагент» (тип значения - Строка) и «ДатаОтгрузки» (тип значения - Дата):

Необходимо при вводе или изменении заказа обеспечить заполнение ячеек «Контрагент» и «ДатаОтгрузки» данными из этого заказа.
Для реализации данной задачи используем обработчик события При изменении поля ввода «Заказ»:
Процедура ТабличноеПолеЗаказовЗаказПриИзменении(Элемент)
// Получить текущую строку табличного поля.
СтрокаТаблицы = ЭлементыФормы.ТабличноеІІолеЗакачов.ТекущаяСтрока: // Ввести значения в ячейки строки.
СтрокаТаблицы.Контрагент = СтрокаТаблицы.Закач.Контрагент: СтрокаТаблицы .ДатаОтгрузки = СтрокаТаблицы.Заказ.ДатаОтгрузки;
КонецПроцедуры
В процедуре в переменную «СтрокаТаблицы» получаем строку табличного поля. Далее работаем с ячейками данной строки. В ячейки «ДатаОтгрузки» и «Контрагент» вносим значения, прочитанные из реквизитов документа, введенного в ячейку «ЗаказПокупателя» данной строки.
Как изменить цвет фона ячейки табличного поля в зависимости от значения, выводимого в нее?
Для того чтобы оформить строки, выведенные в табличное поле, следует использовать обработчик события При получении данных табличного поля.
Допустим, нам необходимо в табличном поле «Товары» выделять красным цветом ячейки колонки «Остаток», если остаток меньше 10, и желтым - если больше 100.
Процедура ТоварыПриПолученииДанныхОлемент. ОформленняСтрок)
Для Каждого ОформлсниеСтроки Из ОформленняСтрок Цикл ЗначениеЯчсйкиОстаток = ОформлениеСтрокн.Ячсйки.Остаток.Значение:
Если ЗначениеЯчейкиОстагок о Неопределено Тогда
Если ЗначениеЯчейкиОстагок < 10 Тогда ОформлсниеСтроки. Ячейки.Остаток.ЦветФона = W сЬЦвета. Крас ный:
ИначеЕслн ЗначениеЯчейкнОстаток > 100 Тогда ОформленнеСтрокн.Ячейки.Остаток.ЦветФона = ??еЬЦвета.Желтый: КонецЕсли;
КонсцЕсли;
КонецЦикла;
КонецПроцедуры
Для решения данной задачи используются параметры процедуры -обработчика события При получении данных. Вторым параметром получаем коллекцию оформлений выводимых строк.
Считывая данные о численном значении остатка, принимаем решение об установке цвета фона ячейки «Остаток» в оформлении строки.
Цвет назначаем, подбирая его из системного набора значений \Л/еЬЦрета.
Как в табличное поле
«ВыбранныеКонтрагенты» добавить новую колонку «Основной Договор», заполнить ее значения и дать возможность открытия этих значений?
Табличное поле «ВыбранныеКонтрагенты» связано с таблицей значений «ТаблицаКонтрагентов» и имеет одну колонку «Контрагент».
|
> омтрагеит |
|
|
[іЯ <Попе ееооа> |
: > |
|
< |
Когда пользователь заполнит ее, он может захотеть увидеть в том же табличном поле еще основные договора контрагентов с возможностью их открытия.
Для решения данной задачи необходимо будет передать управление процедуре со следующим текстом:
Если ТаблицаКонтрагентов.Колонки.НайліСОсновнойДоговор") =
Неопределено Тогда
МасснвТнпов = Новый МассивО;
МассивТипов.Добавить(Тип(”СправочникСсылка.ДоговорыКонтрагентов"));
ОписаннеНужныхТипов = Новый ОписаниеТииов(МассивТипов);
ТаблицаКонтрагеитов.Колонки.ДобавитьС'ОсновнойДоговор",
ОписаниеНужныхТипов);
КонецЕсли:
Для Каждого СтрокаТаблицы нт ТаблицаКонтрагентов Цикл С'трокаТаблицыІ "ОсновнойДоговор"] =
СтрокаТаблицы[''Контрагент'']!"ОсновнойДоговорКонтрагента"]:
КонецЦикла;
Э.іементыФормы.ВыбранныеКонтрагенты.СоідатьКолонкиО: ЭлементыФормы. ВыбранныеКонтрагенты .Колонки.ОсновнойДоговор .Элементу правления.КнопкаОткрытия = Истина;
Поскольку в качестве данных табличного поля выступает таблица «ТаблицаКонтрагентов» - проще задача с добавлением колонок решается именно через эту таблицу значений.
Сначала проверим, нет ли уже у объекта «ТаблицаКонтрагентов» колонки «ОсновнойДоговор». Если нет - добавляем.
Если требуется добавить новую колонку именно определенного типа -сначала создаем объект ОписаниеТипов. К нужным типам в нашем случае пусть относится только
СправочникСсылка.ДоговорыКонтрагентов.
Далее создаем колонку с этим типом значения.
Как Вы понимаете, если потребуется создать колонку с составным типом значения - достаточно будет к массиву «МассивТипов» добавить еще несколько элементов с указанием других нужных типов.
Теперь открываем цикл перебора коллекции строк таблицы значений, в котором для каждой строки в поле с именем «ОсновнойДоговор» присваиваем значение, считанное с реквизита
«ОсновнойДоговорКонтрагента» соответствующего значения поля «Контрагент».
Далее табличному полю «ВыбранныеКонтрагенты» даем команду СоздатьКолонки(). При ее выполнении система удаляет старые колонки и загружает новые из источника данных (таблицы значений «Т аблицаКонтрагентов»).
Теперь остается установить свойство КноПКаОткрытия элемента управления колонки «ОсновнойДоговор» в положение Истина.
В результате пользователь при желании сможет ей воспользоваться.

Как задать список выбора для колонки «ВидДокумента» табличного поля?
В составе табличного поля «ПодборДанных» есть колонка «ВидДокумента», тип значения Строка. Необходимо обеспечить возможность заполнения ее данных выбором значений из видов документов конфигурации.
Если значение вводимых данных может только выбираться из перечня существующих в конфигурации документов - лучше всего войти в свойства колонки «ВидДокумента» и элементом управления указать «Поле выбора».
Далее при открытии формы можно через метаданные прочитать все виды документов конфигурации и передать их в виде списка значений свойству СпиеокВыбора элемента управления колонки «ВидДокумента»:
Процедура ПриОткрытииО
СписокВидовДокументов = Новый СписокЗначений;
Для Каждого ДокументКонфигурации из Метаданные.Документы Цикл СписокВидовДокументов.Добавить(ДокументКонфигурации.Имя): КонецЦикла:
ЭлементыФормы.ПодборДанных .Колонки.ВидДокумента
.ЭлементУправления.СписокВыбора = СписокВидовДокументов: КоиецПроцедуры
Если же по какой-то причине необходимо все же дать возможность пользователю вводить в колонку произвольные виды документов (сверх списка документов текущей конфигурации) - тогда элементом управления колонки «ВидДокумента» необходимо указать «Поле ввода», и интерактивно или программно установить для него свойство КнопкаСпискаВыбора.
Например - так:
ЭлементыФормы. ПодборДанных .Колонки. ВидДокумента
.ЭлементУправления.КнопкаСпискаВыбора = Истина:
Как обеспечить возможность отбора и сортировки данных по реквизитам, не отображаемым в табличном поле формы списка справочника?
ЭлементыФорм ы .С правом н и кСписок
.НастройкаОтбора.ОсновнойПосгавщик.Доступность = Истина; ЭлементыФормы.СправочннкСписок
.НастройкаПорядка.ОеновнойПоставщик.Доступность = Истина;
Как видите, для того, чтобы добавить возможность интерактивного управления отбором и сортировкой по реквизиту «ОсновнойПоставщик» необходимо поработать со свойствами Настрой каОтбора и Настройка Порядка расширения табличного поля списка справочника.
Какреализовать перетаскивание между элементами управления?
Необходимо реализовать возможность заполнения табличной части документа номенклатурными позициями, используя механизм перетаскивания («drag and drop»). Для иллюстрации данной возможности в основной форме документа (в этом случае «Поступление товаров») определим реквизит формы «СправочникСписок» (тип СправочникСписок. Номенклатура). Далее вставим элемент управления ТабличноеПоле и через свойство Данные свяжем его с созданным реквизитом.
У табличного поля, связанного с табличной частью документа отметим свойство Разрешить перетаскивание. У табличного поля, связанного со списком номенклатуры необходимо отметить свойство Разрешить начало перетаскивания.
Определим обработчик события Начало перетаскивания у табличного поля, связанного со списком номенклатуры:
Процедура НоменклатураНачалоПеретаскиванияіЭлемент,
Парамеіры Перетаскивания. Стандартная Обработка)
// Получить значение, переданное системой.
Значение = ПараметрыПеретаскивания.Значение;
// В любом случае значением будет массив.
МасснвЗначсний = Новый Массив;
// Если перетаскивается группа, то в массив записываем входящие в нее элементы Если Значение.ЭтоГ руппа Тогда Выборка = Справочники.Номенклатура.Выбрать(Значение);
Пока Выборка.СледуюшийО Цикл
Если Не Выборка.ЭтоГруппа Тогда МассивЗначений.Добавить(Выборка.Ссылка);
КонецЕсли:
КонецЦикла:
Иначе
МассивЗначений.Добавить(Значение):
КонецЕсли;
// Заполненный массив записываем в параметры.
ПараметрыПеретаскивания. Значение = МасснвЗначсний;
КонецПроцедуры
Обработчик события Проверка перетаскивания у табличного поля, связанного с табличной частью документа.
Процедура ТоварыПроверкаПеретаскивання(Элемент,
ПараметрыПеретаскивания. Стандартная Обработка, Строка,
Колонка)
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Обработчик события Перетаскивание у табличного поля, связанного с табличной частью документа.
Процедура ТоварыПеретаскиваниеОлемент,
ПараметрыПеретаскива
СтандартнаяОбработка
Строка,
Колонка) |
ПИЯ, |
|
ПолученныйМассив = ПарамстрыПеретаскивания.Значсн |
не; |
|
Если ТипЗнч(ПолученныйМассив) = ТипС'Массив") Тогда |
Для Каждого Значение Из ПолученныйМассив Цикл НоваяСтрока = ДокументОбъект.Товары.ДобавитьО; НоваяСтрока.Номенклатура = Значение; НоваяСтрока.Количсство = 1;
КоненЦикла; |
|
|
КонецЕсли; |
|
|
КонсцП роцедуры |
|
В результате получим возможность «набрасывать с помощью мыши» в табличную часть документа номенклатурные позиции справочника либо поодиночке, либо все входящие в «захваченную» группу.
Как вывести остатки на складах в списке номенклатуры?
Для этого в табличное поле, отображающее список справочника «Номенклатура» следует добавить колонку (например, с именем «Остаток») и использовать событие При получении данных табличного поля, отображающего список номенклатуры:
Процедура СписокНоменклатураПриПолученииДанных(Элемент,
ОформлеііияСтрок)
Запрос = Новый Запрос!"ВЫБРАТЬ
I ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток.
I ТоварыНаСкладахОстаткн.Номенклатура.Ссылка КАК Товар |ИЗ
I РегистрНакопления.ТоварыНаСкладах.Остатки(,
Номенклатура В (&МассивТоваров))
КАК ТоварыНаСкладахОстатки”);
МассивНоменклатуры = Новый Массив: // для передачи в параметр запроса Соответствие = Новый Соответствие; // для заполнения остатков в строках
// табличного поля
Для Каждого Строка из ОформленияСтрок Цикл МассивНоменклатуры.Добавить(Строка.ДанныеСтроки.Ссылка);
Соответствие.Вставить(Строка.ДанныеСтроки.Ссылка. Строка);
КоненЦикла;
Запрос.УстановитьПараметр! "МассивТоваров", МассивНоменклатуры);
Выборка = Запрос.Выполннть().ВыбратьО;
// Вывести остаток в строку, найденную в соответствии по номенклатуре // из запроса.
Пока Выборка.Следующий!) Цикл
Соответствие.Получить(Выборка.Товар.Ссылка).Ячейки.Остаток.Значенне =
Выборка.Остаток;
КоненЦикла:
КонецПроцедуры
В параметре «ОформленияСтрок» обработчика этого события передается коллекция оформлений строк, которые были выведены в табличное поле. Это позволяет получать остатки одним запросом для всех выведенных строк, что значительно сокращает время обработки данных.
Другие элементы управления
© В форме есть панель со страницами. Как разместить картинку на закладке?
Допустим, имя панели «ОсновнаяПанель», имя страницы «СчетаУчета», картинка уже есть в библиотеке картинок с именем «ДебетКредит». Тогда так:
ЭлементмФормы.Основная Панель.С'транн цы.СчетаУчета. КартмнкаЗаголовка =
БиблиотекаКартинок.Дебет Кредит;
Если же картинка «свеженарисованная» - необходимо предварительно добавить ее в состав метаданных (раздел «Общие картинки»).
С точки зрения эргономики просьба сильно не увлекаться и применять подобное только в случае необходимости. Картинка приковывает внимание пользователя к закладке, но за счет этого снижается восприятие остальной информации.
® Как обеспечить, чтобы при открытии формы уже записанного элемента справочника «Контрагенты» активной была закладка «СчетаИДоговоры» панели «Панель»?
В модуле формы элемента используем обработчик события
При открытии:
Процедура ПриОткрытииО
Если ЭтоНовыйО = Ложь Тогда ЭлементыФормы.Панель.ТекущаяСтраница = ЭлементыФормы
.Панель
.Страницы
.С четаИДогоноры
КонецЕсли:
КонсцПроцедуры
Убеждаемся, что открываем форму не нового элемента. Далее устанавливаем свойству ТекущаяСтраница панели «Панель» значение требуемой страницы.
Как организовать выбор из нескольких списков документов для открытия?
Необходимо реализовать возможность выбора нескольких списков документов для открытия:
|
Укажите, какие списки документов открыть |
X |
П Платежное поручение исходящее
П Платежное поручение входящее
1 1 Аккредитив переданный
0 Аккредитив полученный
1 1 Платежное требование выставленное
П Платежное требование полученное
0 Инкассовое поручение переданное
0 Инкассовое поручение полученное
1 1 Платежный ордер списание денежных средств |
ок |
|
Отмена ' |
|
|
|
ІИ |
Платежный ордер: поступление денежных средств |
|
і— —.....— -------3 |
|
Это можно выполнить следующим способом:
Док = Метаданные.Документы;
СписокДокументов = Новый СписокЗначенийО; |
|
|
СписокДокументов.Добавить(Док.ГІлатежноеПоручениеИсхоляиіее.. Ложь); СписокДокументов.Добавнть(Док.ПлатежноеПорученнеВходящее,, Ложь); |
|
СписокДокументов.Добавить(Док. Аккре дитивПереланный. |
. Ложь); |
|
СписокДокументов.Добавить(Док.АккредитивПолученный. |
. Ложь); |
|
СписокДокументов.ДобавитмДок.ПлатежноеТребованнеВыставленное,, Ложь); СписокДокументов. Добавить(Док.ПлатежиоеТребованиеПолученное,. Ложь); СписокДокументов.Добавнть(Док.ИнкассовоеПоручеі!иеГІереданное,. Ложь); СписокДокументов. Добавить(Док.ИнкассовосПорученнеПолученное.. Ложь); СписокДокументов.Добавить(Док.ПлатежныйОрдерСписаниеДенежны.\Срсдств,, |
|
Ложь): |
|
|
СписокДокументов.Добавить(Док.ПлатежныйОрдерПоступ |
існнеДенсжныхСредств. |
|
Ложь); |
|
|
Если СписокДокументов |
|
|
.ОтметнтьЭлсменты("Укажите. какие списки документ |
ов открыть”) Тогда |
|
Для Каждого НазваниеДокумента из СписокДокументов Цикл |
|
Если НазваниеДокумента.Пометка Тогда |
|
|
ФормаСписка = Документы! НазваниеДокумента.Значснис. Имя] |
|
• ПолучитьФормуСписка)); |
|
ФормаСписка.ОткрытьО;
КонецЕсли: |
|
|
КонецЦикла; |
|
|
КонецЕсли: |
|
Создаем список значений «СписокДокументов».
Добавляем в список значений элементы, содержащие объекты метаданных документов конфигурации в качестве значения, и ЛОЖЬ в качестве значения свойства Пометка (флажок снят).
Порядок заполнения параметров метода Добавить(): Значение, Представление, Пометка, Картинка.
Далее открываем пользователю модальное окно для установки пометок в списке «СписокДокументов».
Если, установив требуемые пометки, пользователь нажмет «ОК» -открываем цикл перебора элементов «СписокДокуменов». В цикле для тех элементов, на которых пометки установлены, выполняем получение и открытие основной формы списка документа по имени объекта метаданных.
Как можно организовать подстановку обращения кперсоне?
В поле ввода «Персона» пользователь вводит строковые данные с указанием имени абонента. Необходимо по окончании ввода предоставить возможность подстановки начала фразы: «Уважаемый», «Уважаемая»... или никакого.
Николай Федорович
Уважаемый Николай Федорович
Уважаемая Николай Федорович Уважаемое Николай Федорович Уважаемые Николай Федорович Николай Федорович
Для решения данной задачи можно поработать с обработчиком
события Окончание ввода текста поля ввода:
Процедура І1ерсонаОкончаниеВводаТекста(Элемент,
Текст,
Значение.
С тандартнаяОбработка)
Значение = Новый СписокЗначенийО:
Значение.Добавить! "Уважаемый " + Текст): Значение.Добавить("Уважаемая " + Текст); Значение.ДобавитьС’Уважаемое " + Текст): Значение.Добавнть(”Уважаемые" + Текст);
Значение Добавить(Текст);
СтандартнаяОбработка = Ложь;
КонецПроцсдуры
Создаем список значений со всеми возможными значениями обращений и отключаем стандартную обработку события. Теперь, при формировании значеня по имеющемуся в поле ввода тексту (например, при переходе к другому элементу управления по клавише Tab), пользователю будет предоставлена возможность выбрать из нескольких возможных обращений к указанной персоне.
Как в командной панели создать подменю с кнопками?
Допустим, разрабатываемый отчет может формироваться в различных вариантах периодичности, которые содержатся в перечислении «Периодичность». Возможность выбора варианта построения отчета нужно оформить в виде подменю в командной панели « КоманднаяПанельФормы».
Добавление подменю можно организовать следующим образом:
|
Кнопки Командной Панели = ЭлементыФормы. Командная! |
анельФормы. Кнопки; |
|
// Проверить, нет ли уже на командной панели кнопки "С<| |
орммровать". |
|
// Если есть - удалить. |
|
|
Индекс = КнопкиКоманднойПансли |
|
|
.Индекс(КнопкиКоманднойПанели.Найтн("Сформировать'')); |
|
Если Индекс =-1 Тогда |
|
|
Индекс = 0: |
|
|
Иначе |
|
|
КнопкиКоманднойПансли. Удалить! Индекс); |
|
|
КонецЕсли; |
|
|
// Создать подменю "Сформировать''. |
|
|
ПодмснюСформировать = КнопкиКоманднойІ Іансли |
|
|
.Вставить(Индекс, |
|
|
"Сформировать", |
|
|
ТипКнопкиКоманднонПанели. Подменю. |
|
"Сформировать"); |
|
|
//Добавить картинку. |
|
|
ПодмснюСформировать. Картинка = БиблнотскаКартинок.Сформнровать: |
|
ПодменюСформировать.Отображение = ОтображсниеКнопкиКоманднойПанели |
|
НадписьКартинк |
і; |
|
//Опросить перечисление о возможных вариантах периодичности. |
|
Запрос = Новый ЗапросС'ВЫБРАТЬ Ссылка ИЗ Перечисление.Периодичность"); |
|
Выборка = Запрос.Выполітить().Выбрать!); |
|
|
//Добавить кнопки к подменю. |
|
|
Пока Выборка.Следующий!) Цикл |
|
|
Период = Выборка.Ссылка; |
|
|
ПодменюСформировать.Кнонки.ДобавитьГ'кн" + Перио, |
U |
|
ТипКнонкиКоманднойПанели.Действие, |
|
"Сформировал |
за " + Период. |
|
Новый Действие! "КнопкаСформироватьНажатие")); |
|
КонецЦикла; |
|
Поскольку к редактируемой командной панели придется обращаться неоднократно - «положим» ее в переменную
«КнопкиКоманднойПанели».
Далее убедимся, что в командной панели нет кнопки «Сформировать». Для этого сначала пытаемся найти кнопку по имени, а потом определить индекс кнопки в командной панели.
Если такой кнопки нет - индекс имеет значение «-1», для дальнейшего создания нужной кнопки переменной «индекс» присвоим «О». Таким образом, наша кнопка будет первой слева, хотя могли бы установить ее любой другой по порядку.
Если же индекс кнопки «Сформировать» не равен «-1» - он
пригодится для удаления кнопки. Удаляем кнопку по индексу.
Теперь можно приступить к созданию подменю «Сформировать». Указываем в качестве параметров индекс, имя, тип и название создаваемой кнопки. Обратите внимание, все элементы объекта КнопкиКоманднойПанели это объекты
КнопкаКоманднойПанели. А вот свойство Тип объекта КнопкаКомандноЙПанели уже назначается из системного перечисления ТипКнопкиКомандноЙПанели. В нашем случае - это Подменю.
По умолчанию на созданной кнопке отображен только текст. Если хотим разместить еще картинку - необходимо указать значение свойства Картинка (передаем картинку из коллекции, хранящейся в библиотеке картинок данной конфигурации). Если будете назначать свою - не забудьте, что размер картинки для кнопки должен быть небольшим (оптимально - 16x16 пикселей). Чтобы картинка не вытеснила текст — устанавливаем свойству Отображение соответствующее значение.
Теперь соберем запросом все возможные значения из перечисления «Периодичность», поскольку запрос позволяет обратиться к нужной таблице.
В цикле перебора выборки из результата запроса добавляем к нашему подменю кнопки аналогично тому, как добавляли само подменю к командной панели. Единственное отличие - для кнопок указываем последним параметром действие, которое создаем конструктором, с указанием вызываемой процедуры - обработчика события Нажатие на кнопку.
|
Тело вызываемой процедуры может выглядеть так: |
|
Процедура КнопкаСформнроватьНажатне(Элемент) |
|
|
Название! Іериоднчносгн = СтрЗаменитцЭлемент.Имя,' |
кн".'”'); |
|
КонецПроцедуры |
|
|
Получаем название периода из самого названия кнопки, заменив приставку «кн» на пустую строку. Теперь, опираясь на это название, можно выполнить в том или ином виде отчет.
Как созданной кнопке назначить «горячие клавиши»?
Допустим кнопке «СозданнаяКнопка» нужно назначить комбинацию клавиш «Ctrl+Alt+L».
СозданнаяКнопка.СочстаннеКлавнш =
Новый СочетавиеКлавиш( Клавишах, Истина. Истина.)
Устанавливаем значение свойству СочетаниеКлавиш значение, полученное конструктором НОВЫЙ. Первым параметром конструктору нужно передать основную клавишу сочетания. Ее значение берем из системного перечисления Клавиши.
Остальными параметрами передаем признак участия других клавиш: вторым - «Alt»; третьим - «Ctrl», четвертым - «Shift».
Замечания: горячие клавиши можно назначать только кнопкам с типом «Действие» (не подменю, и не разделитель).
И обратите внимание на значения системного перечисления Клавиша - русских букв там нет.
Как реализовать заполнение возможных значений поля выбора «ОбрабатываемаяТабличнаяЧасть» при заполнении поля ввода «ОбрабатываемыйДокумент»?
Есть поле ввода «ОбрабатываемыйДокумент». В качестве данных -реквизит формы «ОбрабатываемыйДокумент» (тип значения -ДокументСсылка).
Есть поле выбора «ОбрабатываемаяТабличнаяЧасть». В качестве данных - реквизит формы «ОбрабатываемаяТабличнаяЧасть» (тип значения - Строка, имеется в виду представление обрабатываемой табличной части).
Необходимо обеспечить, чтобы при выборе пользователем значения «ОбрабатываемыйДокумент» заполнялся список выбора поля ввода «ОбрабатываемаяТабличнаяЧасть».
Для решения этой задачи используем обработчик события При изменении поля ввода «ОбрабатываемыйДокумент»:
Процедура ОбрабатываемыйДокументПриИзменеиии(Элемент)
СписокВыбора = ЭлементыФормы
.ОбрабатываемаяТабличнаяЧасть
.СписокВыбора:
СписокВыбора. Очистить!);
Если Элемент.Значение о Неопределено И Не(Элемент.Значение.ПустаяО) Тогда ТабличныеЧасти = Элемент.Значение.МетаданныеО.ТабличныеЧасти;
Для Каждого ТабличнаяЧасть из ТабличныеЧасти Цикл СписокВыбора.Добавить(ТабличнаяЧасть):
КонецЦикла:
КонецЕсли;
КонецПроцедуры_
Сначала создаем переменную «СписокВыбора», содержащую список выбора поля «ОбрабатываемаяТабличнаяЧасть». Очищаем его, чтобы при последующих выборах других документов в качестве обрабатываемых - список выбора не разрастался.
Далее определяем, что в качестве значения «ОбрабатываемыйДокумент» указана ссылка на конкретный документ.
Через метод Метаданные() определяем коллекцию табличных частей документа. В цикле их перебора добавляем значения к списку выбора поля «ОбрабатываемаяТабличнаяЧасть».
Кроме того, желательно побеспокоится о возможности очистки значения поля ввода «ОбрабатываемыйДокумент». Скорее всего - есть смысл при этом очистить и поле выбора «ОбрабатываемаяТабличнаяЧасть».
Этого можно добиться посредством обработчика события Очистка поля ввода «ОбрабатываемыйДокумент»:
Если пользователь указал несколько дат в поле календаря - как их перебрать?
Если элемент управления ПолеКалендаря имеет режим выделения даты Множественный, пользователь может выделить несколько дат на календаре:

Выделенные пользователем даты легко перебрать следующим образом:
КоллскцияДат — ЭлсмснтыФормы.ПолсКалендаря.ВыделеннысДаты
Для каждого ДатаКалендаря из КоллекцияДат Цикл Сообщить; Дата Календаря):
КонецЦикла:
Как видите, свойство поля календаря ВыделенНЫвДаты содержит коллекцию указанных пользователем дат.
Сам же режим множественного выбора может включаться интерактивно в конфигураторе посредством соответствующего свойства элемента управления. Или таким образом:
Элемені мФормы.ПолеКалсмларя.Режим Выделения = РежимВыделенияДаты
.Множественный;
В данном случае значение свойству было назначено из системного перечисления РежимВыделенияДаты.
® Как организовать работу с индикатором?
Допустим, у нас есть «РезультатЗапроса». Работа с перебором его выборки занимает много времени. Тогда, чтобы показать пользователю прогресс процесса, можно добавить в форму элемент управления
Индикатор.
Пусть его имя будет «ИндикаторПеребора». В свойствах данного элемента управления можно указать сразу начальное и максимальное значения; ориентацию продвижения процессора (слева-направо или сверху-вниз); стиль отображения - или гладкий, или прерывистый, или прерывисто-наклонный (выбирается из системного перечисления РежимСглаживанияИндикатора); отображать или не отображать проценты.
В теле же выполняемой процедуры необходимо лишь в нужные моменты присваивать значение свойству Значение индикатора.
Например, так:
Выборка = РезультатЗапроса.Выбрать();
Индикатор = ЭлементыФормы.ИндикаторПеребора: Мндикатор.МаксиматьноеЗначенне = Выборка. Количество;); Индикатор.Значенне = О;
Пока Выборка.Следующий() Цикл Индикатор.Значение = Индикатор.Значенне + 1;
КонецЦикла:
Выполняем выборку по результату запроса. В цикле на каждом шаге присваиваем значение индикатору на единицу большее предыдущего.
Обратите внимание - свойствами индикатора можно управлять и средствами языка:
Выборка = РезультатЗапроса.ВыбратьО;
Индикатор = ЭлементыФормы.ИндикаторПеребора; Индикатор.МаксимальноеЗначение = Выборка.Количество(); Индикатор.Значение = 0;
Иидикатор.ОтображатьПроценты = Истина;
Индикатор.С'тильОтображсния - РежимСглаживанияИн.ти кагора. Прерывистый Индикатор.Ориентация = Ориентация.Вертикально;
Индикатор.Шаг = 0.1;
Пока Выборка.СледующийО Цикл Индикатор.Значение = Индикатор.Значение + I;
КонецЦикла;
Как у элемента управления сменить источник данных?
Необходимо у элемента управления менять значение установленное в свойстве Данные.
Предположим, что существует форма, у которой есть два реквизита:
СписокКонтрагентов
СправочникСписок.Контрагенты); |
(тип |
Спис окНоменклатуры
СправочникСписок.Номенклатура). |
(тип |
В диалоге размещен элемент управления ТабличноеПоле (имя «ТП»). Необходимо, чтобы в зависимости от действий пользователя через данный элемент управления можно было работать как со списком справочника «Номенклатура», так и со списком справочника « Контрагенты ».
Следующая процедура «переключит» табличное поле в «режим» работы со справочником «Контрагенты».
Процедура КнопкаВыполмнтьНажатие(Элемент)
ЭлементыФормы.ТП.Данные = "СписокКонтрагентов" ЭлементыФормы.ТП.СоздатьКолонкиО;
КонецПроцедуры_
Следующая процедура «переключит» табличное поле в «режим» работы со справочником «Номенклатура».
Процедура Номенклатура! Кнопка)
ЭлементыФормы.ТП.Данные = “СписокНоменклатуры"; ЭлементыФормы.ТП.СоздатьКолонкиО;
КонецПроцедуры
ф Как задать представление даты, отображаемое в поле ввода по-умолчанию?
Для этого нужно воспользоваться свойством Формат поля ввода и в форматной строке задать требуемое значение параметра ДП, отвечающего за представление «пустой» даты.
Если поле ввода отображает только дату, может использоваться, например, следующее значение:

Если поле ввода отображает только время, может использоваться, например, следующее значение:

Если поле ввода отображает и дату, и время, может использоваться, например, следующее значение:
|
Аналогичного результата можно добиться программным способом: |
|
ЭлементыФормы.ПолеВводаІ. Формат = ”ДП='01.01.0001'"; |
|
// Или
ЭлементыФормы.ПолеВводаІ.Формат = "ДП='00:00:00"’: |
|
|
// Или |
|
|
ЭлементыФормы.ПолеВводаІ.Формат = "ДП='01.01.0001 00:00:00"'; |
|
ф Как вывести текст в поле картинки в том случае, если картинка не выбрана?
Для этого следует использовать свойство
ТекстНевыбраннойКартинки элемента управления ПолеКартинки.
Его можно задать при конфигурировании:

или программно:
Элементы Формы.ОсиовііоеИіображение.ТекстНевыбраннойКартинки = _"фотография номенклатуры отсутствует
В результате, в случае, если картинка не выбрана, в поле картинки будет выведен указанный текст:

ф Как открыть пользователю стандартный диалог выбора цвета?
Для работы со стандартным диалогом выбора цвета предназначен объект ДиалогВыбора Цвета. Организовать выбор цвета пользователем можно с помощью следующего кода:
Диалог = Новый Диалоі ВыбораЦвста:
Если Диалог.ВыбратьО Тогда ВыбранныйЦвет = Диалог.Цвет; КонсцЕслн;
Аналогичным образом организуется и выбор шрифта при помощи стандартного диалога (используется объект ДиалогВыбораШрифта):
Диалог = Новый ДиалогВыбораШрифта:
Если Диалог.ВыбратьО Тогда ВыбранныйШрифт = Диалог.Шрифт; КонецЕсли;
Следует заметить, что в тех случаях, когда выбор цвета или шрифта пользователь должен выполнять в форме (например, в форме отчета), достаточно просто разместить в этой форме поля ввода с соответствующими типами значений (Цвет или Шрифт). Тогда при нажатии на кнопку выбора в режиме 1С:Предприятие будет открыт стандартный диалог выбора цвета (шрифта), а выбранное пользователем значение сохранено в реквизите формы, связанном с данным полем ввода.
Как заполнить список в форме данными запроса?
Для наиболее быстрого вывода результата запроса в список, расположенный в форме, можно воспользоваться методом глобального контекста ЗаполнитьЗначбНИяСв<ЭЙСТВ(). При этом следует полям запроса установить псевдонимы, соответствующие свойствам элемента списка значений:
Запрос = Новый ЗапросС |ВЫ БРАТЬ
I Номенклатура.Сеылка КАК Значение,
I Номенклатура.Представление КАК Представление.
I ИСТИНА КАК Пометка |ИЗ
I Сиравочннк.Номенклатура КАК Номенклатура |ГДЕ
I Номенклатура.ОсновнойПоставщик = &ОсновнойПоставщик”);
Запрос.УстановитьПараметрІ "ОсновнойПоставщик", ПолеПоставшнк);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.СледуюшийО Цикл
ЗаполнитьЗначенияСвойств(ПолеСписка.Добавить(). Выборка): КонецЦикла;
© Как отобразить в форме файл графической схемы?
Для этого необходимо разместить в форме поле графической схемы (например, «СтруктурнаяСхема»), а затем выполнить чтение файла графической схемы и вывод его в поле, расположенное в форме:
Схема = Новый ГрафическаяСхсмаО; CxeMa.npo4HTaTb(''D:/MyScheme,grs");
ЭлементыФормы.СтруктурнаяСхема.УстановитьСхему(Схеча):
Интерфейсы, стили
CD Как задать различные стили 1С:Предприятиядля различных категорий пользователей?
Для этого следует воспользоваться свойством глобального контекста
ГлавныйСгиль:
ОсновнойИнтерфейс = ПольтователиИнформанионнойБазы .ТекуіцийПользовательІ) .ОсновнойИнтерфейс .Имя;
Если ОсновнойИнтерфейс = "ИнтерфейсКассира" Тогда ГлавныйСтиль = БиблиотекаСтилей.СтильКассира;
ИначеЕсли ОсновнойИнтерфейс = "Планирование" Тогда
ГлавныйСтиль = БиблиотекаСтилей.СтильПланирования;
Иначе
ГлавныйСтиль = БиблиотекаСтилей.Основной; КонецЕсли;
Следует учитывать, что изменение данного свойства возможно только до того, как открыто главное окно приложения (например, в обработчике
события приложения Перед началом работы системы).
Есть список имен интерфейсов с пометками. Как сделать помеченные интерфейсы видимыми?
СтрокаИменИнтерфейсов =
Для Каждого ИмяИнтерфейса ич СписокИнтерфесов Цикл Если ИмяИнтерфейса.Пометка Тогда
СтрокаИменИнтерфейсов = СтрокаИменИнтерфейсов + ИмяИнтерфейса + КонецЕсли:
КонецЦикла;
ГлавныйНн юрфейс.І ІсрсключитьИнтсрфсйс(СтрокаИ мен Интерфейсов):
Создаем строковую переменную «СтрокаИменИнтерфейсов» для указания через запятую имен помеченных интерфейсов.
В цикле перебора списка заполняем ее.
Посредством свойства глобального контекста Главный Интерфейс требуем снять видимость всех интерфейсов и включить видимость только тех, чьи имена перечислены в строковой переменной «СтрокаИменИнтерфейсов».
Замечание: для интерфейсов, у которых свойство Переключаемый будет иметь значение Ложь - отключение не произойдет. Обычно такое привилегированное положение занимает некий «базовый» интерфейс, содержащий хотя бы меню «Файл» и «Справка».
Как из формы обработки отключить глобальный обработчик ожиданий?
Обработчик ожидания есть и у формы, и у глобального контекста. Поэтому если обработчик ожидания включен в модуле приложения, то отключать его следует тоже из модуля приложения.
Например, подключение:
11роцсдура ГІрнІІача іеРаботыСистемы() ПодключитьОбработчикОжішаішяСПронеркаОпроса", 60);
КонецПроцедуры
Отключение - в процедуре модуля приложения:
Процедура ОткачОтОпросаО Экспорт ОтключитьОбработчикОжиданияС'ПроиеркаОпроса’'); КонецПроцедуры
А в форме обработки - вызов процедуры:
ОткатОтОпросаі >
Поскольку процедура «ОтказОтОпроса» в модуле приложения написана с указанием ключевого слова Экспорт - управление будет передано на нее, и в результате - добьемся желаемого.
Запросы, отчеты
Запросы
Как получить данные из табличной части документов?
Например, требуется получить все номенклатурные позиции, указанные в табличной части «Товары» документов «РеапизацияТоваровУслуг».
Для этого можно воспользоваться запросом со следующим текстом:
ВЫБРАТЬ РАЗЛИЧНЫЕ
РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура ИЗ
Документ.РсализацияТоваровУ слуг .Товары КАК РеализацияТоваровУслугТовары
В качестве источника указываем табличную часть документов -таблицу «Документ. РеализацияТоваровУслуг.Товары».
Выходным полем объявляем поле «Номенклатура», входящее в состав таблицы источника.
Кроме того, поскольку одна и та же товарная позиция, естественно, могла присутствовать и не один раз в документах - применяем РАЗЛИЧНЫЕ для получения только различных строк в выходной таблице запроса.
В результате получим таблицу вида:
_Номенклатура_
Женские ботфорты коричневые_
Ботинки женские демисезонные_
Ботинки женские натуральная кожа_
Женские босоножки_
Комбайн кухонный B1NATONE FP 67_
Кофеварка BRAUN KF22R_
Как получить данные из табличной части документов и представить их в иерархическом виде?
Например, требуется получить все номенклатурные позиции, указанные в табличной части «Товары» документов «РеализацияТоваровУслуг» с указанием иерархии номенклатуры.
Для этого можно воспользоваться запросом со следующим текстом:
ВЫБРАТЬ РАЗЛИЧНЫЕ
РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары ИТОГИ ПО
Номенклатура ТОЛЬКО ИЕРАРХИЯ_
В качестве источника указываем табличную часть документов -таблицу «Документ.РеализацияТоваровУслуг.Товары».
Выходным полем объявляем поле «Номенклатура», входящее в состав таблицы источника, применяем РАЗЛИЧНЫЕ для получения только различных значений в выходной таблице запроса.
Далее вводим промежуточные итоги только по группам, в состав которых входят найденные в документах номенклатурные позиции.
Если иерархию результата запроса отображать при помощи отступов, получится следующее:

Замечание: при помощи предложения ИТОГИ ПО к результату запроса добавляются записи с промежуточными итогами. Проще говоря -записей будет больше, нежели без применения данного предложения.
Как подсчитать количество одинаковых элементов в выбираемых данных?
Например, требуется получить список номенклатуры, встречающейся в документах «Реализация товаров и услуг» с указанием общего количества каждой позиции номенклатуры по всем документам.
При решении данной задачи опять же необходимо иметь в виду, что один и тот же товар мог встречаться в документах не один раз. Однако если и на этот раз применить РАЗЛИЧНЫЕ, то получим в результате только различные строки. То есть один и тот же товар может встречаться в комбинациях с разным количеством:
|
Номенклатура |
Количество |
|
Женские ботфорты коричневые |
1,000 |
|
Женские ботфорты коричневые |
3,000 |
|
Женские ботфорты коричневые |
10,000 |
|
Ботинки женские демисезонные |
1,000 |
|
Ботинки женские демисезонные |
2,000 |
|
Ботинки женские натуральная кожа |
1,000 |
|
Ботинки женские натуральная кожа |
2,000 |
Поэтому для решения нашей задачи необходимо воспользоваться операцией СГРУППИРОВАТЬ ПО с вычислением агрегатной функцией СУММА() по полю «Количество»:
ВЫБРАТЬ
РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура. СУММА(РеалнзацияТоваровУслугТовары.Количество) КАК Количество ИЗ
Доку мент. Реал изацияТоваровУ слуг.Товары КАК РеализацияТоваровУслугТовары
СГРУППИРОВАТЬ ПО РеализацияТоваровУслугТовары. Номенклатура
Групповым полем указано поле «Номенклатура». В результате получим таблицу вида:
|
Номенклатура |
Количество |
|
Женские ботфорты коричневые |
49 |
|
Ботинки женские демисезонные |
6 |
|
Ботинки женские натуральная кожа |
6 |
|
Женские босоножки |
19 |
|
Комбайн кухонный BINATONE FP 67 |
13 |
|
Кофеварка BRAUN KF22R |
6 |
Замечание: при помощи СГРУППИРОВАТЬ ПО результат запроса сворачивается (сжимается) «вокруг» групповых полей. Просто говоря -записей будет меньше, нежели без применения данного предложения.
Кроме того, для правильного применения СГРУППИРОВАТЬ ПО все выходные поля должны быть или групповыми, или результатами вычисления агрегатных функций.
Как применять условия для отбора по значениям полей, вычисленных как результат агрегатной функции?
Если к вышеприведенному примеру (Как из табличной части «Товары» документов «РеализацияТоваровУслуг» получить все номенклатурные позиции с суммированием количества?) добавить еще условие выводить только те записи, где просуммированное количество больше 10, тогда текст запроса выглядел бы так:
ВЫБРАТЬ
РеашпацияТоваровУслугТовары.Номенклатура КАК Номенклатура,
СУ ММ АСРеализацняТоваровУслутТовары. Количество) КАК Количество ИЗ
Документ. Реал изацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
СГРУППИРОВАТЬ по РеализацияТоваровУслугТовары. Номенклатура ИМЕЮЩИЕ
СУММА(РеализацияТоваровУелугТовары.Количество) > 10
Для реализации условия отбора на значения агрегатных функция применяется предложение ИМЕЮЩИЕ. В результате получим таблицу вида:
|
Номенклатура |
Количество |
|
Женские ботфорты коричневые |
49 |
|
Женские босоножки |
19 |
|
Комбайн кухонный BINATONE FP 67 |
13 |
Замечание: не путайте с условием ГДЕ. Это условие налагается на исходные записи. В результате, если бы не было ни одного из документов, где количество товара в строке больше 10 - результатом запроса была бы пустая таблица.
Как ограничить выборку из виртуальной таблицы?
Для этого лучше всего выполнить запрос по виртуальной таблице соответствующего оборотного регистра «Продажи». Дело в том, что данный регистр и предназначен для решения этой задачи. Именно в нем уже собрана из различных документов (регистраторов) необходимая информация.
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура ИЗ
РегистрНакопления.Продажи.Оборотыі&ДатаНач, &ДатаКон) КАК ПродажиОбороты
В качестве источника выбираем таблицу
«РегистрНакопления.Продажи.Обороты». В качестве параметров задаем для нее дату начала и дату окончания периода, за который необходимо собрать обороты.
Обратите внимание, виртуальная таблица - самогруппируема. Детальность ее записей определяется составом ее же выходных полей.
Какпросуммировать данные по одинаковым значениям одного из полей выборки?
Например, требуется получить информацию о продажах товаров с подведением итогов по объемам продаж подразделениями:
|
Подразд. |
Номенклатура |
Кол-во
Оборот |
Стоимость
Оборот |
|
Отдел оптовой пр одажи |
|
|
58 167,12 |
|
Отдел оптовой пр одажи |
Женские ботфорты кор
ичневые |
49,000 |
4 430,39 |
|
Отдел оптовой пр одажи |
Ботинки женские деми
сезонные |
6,000 |
246,69 |
|
Отдел оптовой пр одажи |
Ботинки женские натур
альная кожа |
6,000 |
320,44 |
|
Отдел оптовой пр одажи |
Женские босоножки |
19,000 |
1 028,23 |
|
Отдел оптовой пр одажи |
Комбайн кухонный BI NATONE FP 67 |
13,000 |
5 493,73 |
|
Отдел оптовой пр одажи |
Кофеварка BRAUN KF 22R |
6,000 |
4 427,36 |
|
Отдел розничной продажи |
|
|
632,33 |
|
Отдел розничной продажи |
Причуда (вафли) |
5,000 |
2,36 |
|
Отдел розничной продажи |
Принц (печенье) |
4,000 |
4,01 |
|
Отдел розничной продажи |
Сердечко (печенье) |
5,000 |
3,83 |
Поскольку в оборотном регистре «Продажи» есть измерения «Номенклатура» и «Подразделение», решить задачу можно посредством следующего запроса:
|
ВЫБРАТЬ |
|
|
ПродажиОбороты.Подразделение КАК Подразделение. ПродажнОбороты.Номенклатура КАК Номенклатура. ПродажиОбороты.КоличествоОборот, |
|
|
ПродажиОбороты.СтоимостьОборот КАК СтоимостьОборот |
|
ИЗ |
|
|
Реі исгрНакопления.Продажи.Оборогы((&ДатаНач, &Да |
га Кон) |
|
КАК ПродажиОбороты |
|
|
ИТОГИ СУММА(СтоимостъОборот) НО |
|
|
Подразделение |
|
В качестве источника используем виртуальную таблицу регистра с указанием временных параметров для ограничения интервала сбора оборотов продаж.
В качестве выходных полей указываем «Подразделение» и «Номенклатура», плюс обороты по нужным ресурсам.
Для того, чтобы добавить промежуточные итоги по полю «Подразделение» используем ИТОГИ ПО. Причем для итоговых записей применяем агрегатную функцию СУММА() для поля «СтоимостьОборот».
Как получить только те записи, в которых значение определенного поля превышает указанное значение?
Например, требуется получить информацию о продажах товаров определенным подразделением в количестве, превышающем некоторое пороговое значение.
При решении этой задачи для оборотного регистра «Продажи», в составе которого присутствуют измерения «Номенклатура» и «Подразделение», можно выполнить запрос со следующим текстом:
ВЫБРАТЬ
ПродажиОбороты.Подразделение КАК Подразделение.
ПродажиОбороты.Номенклатура КАК Номенклатура, ПродажиОбороты.КоличествоОборот.
ПродажиОбороты.СтоимостьОборот КАК СтонмостьОборот ИЗ
РегистрНакоиления.Продажи.Обороты(&ДатаНач.
&ДатаКон,,
Подразделение = &Подразделение)
КАК ПродажиОбороты
ГДЕ
ПродажиОбороты.КоличествоОборот > &Порог_
В качестве источника используем виртуальную таблицу «РегистрНакопления.Продажи.Обороты» с отборами по началу и концу периода сбора оборотов, и с отбором по значению измерения «Подразделение». Обратите внимание, применение отбора уже в виртуальной таблице позволяет существенно повышать быстродействие запроса. Поскольку отбор сработает еще при построении виртуальной таблицы.
Для оборота по ресурсу отбор можно применить уже только после построения виртуальной таблицы, поскольку именно она и вычисляет это значение. Значит, отбор записей с количеством продаж, превышающим пороговое значение, производим посредством предложения ГДЕ.
Как обратиться к подчиненным полям в запросе?
Например, требуется получить данные о продажах контрагентам, но в регистре «Продажи» нет измерения «Контрагент», а есть только измерение «ДоговорКонтрагента».
Поскольку справочник «Договора» явл5*ется подчиненным справочнику «Контрагенты», то по сути дела идет речь о получении данных в разрезе владельцев договоров, попавших в данные регистра.
В подобных случаях можно пользоваться так называемым «разыменованием» полей, когда к нужному полю можно «добраться через точку»:
ВЫБРАТЬ
ПродажиОбороты .ДоговорКонтратента.Владелец. ПродажиОбороты.КолнчествоОборот.
ПродажиОбороты.СтоимостьОборот КАК СтоимостьОборот ИЗ
РегистрНакопления. Продажи. Обороты(&ДатаНач, ДДатаКон) КАК ПродажиОбороты
Если у одного контрагента может существовать несколько договоров, следует использовать группировку по владельцу договора, чтобы для каждого контрагента выводилась только одна строка:
ВЫБРАТЬ
ПродажиОбороты .ДоговорКонтрагента. Владелец,
СУММА(ПродажнОбороты.КоличествоОборот) КАК КоличествоОборот. СУММА(ПродажиОбороты.СтоимостьОборот) КАК СтоимостьОборот ИЗ
РегистрНакопления.Продажи.ОборотыК&ДатаНач, &ДатаКон)
КАК ПродажиОбороты
СГРУППИРОВАТЬ НО
ПродажиОбороты.ДоговорКонтрагента.Владелец
Как объединить результаты нескольких запросов?
Например, требуется получить данные обо всех номенклатурных позициях, использованных во всех табличных частях документов «Реализация товаров и услуг».
В составе документов есть три табличных части «Товары», «ВозвратнаяТара» и «Услуги». В составе каждой из частей есть реквизит «Номенклатура».
Поскольку данные необходимо собрать со всех таблиц табличных частей - данную задачу можно решить посредством объединения запросов:
ВЫБРАТЬ РАЗЛИЧНЫЕ
РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура ИЗ
Документ.РеализацняТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ОБЪЕДИНИТЬ ВЫБРАТЬ РАЗЛИЧНЫЕ
РеализацияТоваровУслугВозвратнаяТара. Номенклатура ИЗ
Документ. Реал изацияТоваровУ слуг. ВозвратнаяТ ара КАК РеализацияТоваровУслугВозвратнаяТара
ОБЪЕДИНИТЬ ВЫБРАТЬ РАЗЛИЧНЫЕ Реал изацияТоваровУ слугУслуги.Номенклатура ИЗ
Докумснт.РеализацияТоваровУслуг.Услуги КАК РеализаиняТоваровУслугУслуги
Получаем по табличной части «Товары» документа записи с различными значениями поля «Номенклатура», далее объединяем их с аналогично полученными записями по остальным табличным частям. Из-за того, что применили ОБЪЕДИНИТЬ Е СЕ в
результате запроса останутся только разные строки даже в случае, если какая-то номенклатурная позиция оказалась указанной и в качестве товара и в качестве, например, тары (в нескольких таблицах). То есть, одинаковые строки заменятся одной.
Замечание: объединение приводит, если выразиться проще, к добавлению строк в результат запроса.
При использовании объединения обязательно должно совпадать количество выходных полей объединяемых запросов.
Как выбрать данные из двух таблиц, удовлетворяющие определенному условию?
Например, требуется получить данные о товарах, которые заказаны как покупателями, так и поставщикам.
Данные о товарах, заказанных покупателями, хранятся в регистре остатков « Заказы П оку пате л ей ».
Данные о товарах, заказанных поставщикам, хранятся в регистре остатков «ЗаказыПоставщикам».
Необходимо получить таблицу вида:
|
Номенклатура |
Заказано
Покупателями |
Заказано
Поставщикам |
|
Ботинки женские демисезонные |
20,000 |
180,000 |
|
Ботинки женские натуральная кожа |
12,000 |
120,000 |
|
Женские босоножки |
13,000 |
140,000 |
|
Комбайн кухонный BINATONE FP 67 |
1,000 |
150,000 |
|
Кофеварка BRAUN KF22R |
4,000 |
150,000 |
Поскольку речь идет о получении данных по товарным позициям, находящихся в остатках и одной и другой таблицы - решить задачу можно за счет применения внутреннего соединения таблиц источников:
ВЫБРАТЬ
ЗаказыПокупателейОстатки.Номенклатура.
ЗаказыПокупатслейОстатки.КоличествоОстаток КАК ЗаказаноПокупатслями, ЗаказыПоставщикамОстатки.КолнчествоОстаток КАК ЗаказамоПоставщикам ИЗ
РегистрНакоплен ия. Заказы! Іокупателей.Остатки(&Дата(>тч)
КАК ЗаказыПокупателейОстатки ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакоплення .Заказы Поставщикам .Остаткн(&ДагаОтч)
КАК ЗаказыПоставщикамОстатки ПО
ЗаказыПокупателейОстатки.Номенклатура =
ЗаказыПоставщикамОстатки.Номенклатура
Соединение проводим по выполнению условия равенства полей «Номенклатура» обоих источников.
Замечание: Соединение обычно используется, если выразиться проще, для добавления колонок из других источников к результату запроса.
Как дополнить данные одной таблицы данными, выбранными из другой таблицы по определенному условию?
Например, требуется получить количественные данные о товарах, заказанных покупателями, с информацией о том, в каком количестве они заказаны поставщикам (и заказаны ли вообще).
Данные о товарах, заказанных покупателями, хранятся в регистре остатков «ЗаказыПокупателей».
Данные о товарах, заказанных поставщикам, хранятся в регистре остатков «ЗаказыПоставщикам».
Необходимо получить таблицу вида:
|
Номенклатура |
Заказано
Покупателями |
Заказано
Поставщикам |
|
Женские ботфорты коричневые |
9,000 |
|
|
Ботинки женские демисезонные |
20,000 |
180,000 |
|
Ботинки женские натуральная кожа |
12,000 |
120,000 |
|
Женские босоножки |
13,000 |
140,000 |
|
Комбайн кухонный BINATONE FP 67 |
1,000 |
150,000 |
|
Кофеварка BRAUN KF22R |
4,000 |
150,000 |
|
Вентилятор оконный |
13,000 |
|
|
Вентилятор OPBHTA,STERLING,Hn. |
6,000 |
|
Данную задачу можно решить за счет применения левого внешнего соединения данных источников в запросе:
ВЫБРАТЬ
ЗаказыПокупателейОстатки.Помснклатура,
ЗаказыПокупателейОстаткн.КоличествоОстаток КАК ЗаказаноПокупателями. ЗаказыПоставщикамОстатки.КоличествоОстаток КАК ЗаказаноПоставшикам ИЗ
РепістрНакопления.ЗаказыПокупателей.Остатки(&ДатаОтч)
КАК ЗаказыПокупателейОстагки ЛЕВОЕ СОЕДИНЕНИЕ
РегистрНакоіілеиия.ЗаказыПоставщикам.Остатки(&Да гаОтч)
КАК ЗаказыІ ІосгавшикамОстатки ПО
ЗаказыПокупателейОстатки Номенклатура =
ЗаказыІІоставщикамОстатки.Номенклатура
Замечание: по номенклатуре, остатков которой нет в регистре «ЗаказыПоставщикам» в записях результата запроса поле «ЗаказаноПоставщикам» будет содержать значение NULL. He путать с нулевым значением! NULL - это не число!
Как объединить данные из двух таблиц по определенному условию?
Например, требуется получить количественные данные по всем номенклатурным позициям, которые либо заказаны поставщикам, либо заказаны покупателями.
Данные о товарах, заказанных покупателями, хранятся в регистре остатков «ЗаказыПокупателей».
Данные о товарах, заказанных поставщикам, хранятся в регистре остатков «ЗаказыПоставщикам».
Необходимо получить таблицу вида:
|
Номенклатура |
Заказано
Покупателями |
Заказано
Поставщикам |
|
Женские ботфорты коричневые |
9,000 |
|
|
Ботинки женские демисезонные |
20,000 |
180,000 |
|
Ботинки женские натуральная кожа |
12,000 |
120,000 |
|
Женские босоножки |
13,000 |
140,000 |
|
Комбайн кухонный BINATONE FP 67 |
1,000 |
150,000 |
|
Кофеварка BRAUN KF22R |
4,000 |
150,000 |
|
Вентилятор оконный |
13,000 |
|
|
Вентилятор OPBHTA,STERLING,Hn. |
6,000 |
|
|
Кроссовки мужские, кожа |
10,000 |
100,000 |
|
Кофеварка JACOBS (Австрия) |
|
150,000 |
|
Полусапожки на шнурках |
|
100,000 |
Данную задачу можно решить посредством полного соединения:
ВЫБРАТЬ
ВЫБОР
КОГДА (ЗаказыПокупателейОстатки.Номенклатура) ЕСТЬ NULL ТОГДА ЗаказыПоставщикамОстатки.Номенклатура ИНАЧЕ
ЗаказыПокупателейОстатки.Номенклатура КОНЕЦ КАК Номенклатура.
ЗаказыПокупателейОстатки.КоличествоОстаток КАК ЗаказаноПокупателями. ЗаказыПоставщикамОстатки.КоличествоОстаток КАК ЗаказаноПоставщикач ИЗ
РетистрНакопления.ЗаказыПокуиателей.Остатки(&ДатаОтч)
КАК ЗаказыПокупателейОстатки ПОЛНОЕ СОЕДИНЕНИЕ
РегистрНакопления.ЗаказыПоставшикам.Остатки(&ДатаОтч)
КАК ЗаказыПоставщикамОстатки ПО
ЗаказыПокупателейОстатки. Номенклатура =
ЗаказыПоставщикамОстатки.Номенклатура
Обратите внимание, пришлось поле «Номенклатура» формировать данными другой таблицы-источника для случаев, когда товар только заказывался поставщику, но не заказывался покупателями.
Или подобный результат можно получить за счет группирования данных вложенного запроса, полученного объединением запросов:
|
ВЫБРАТЬ |
|
ВложенныйЗапрос. Номенклатура,
СУММ А(ВложенныйЗапрос.ЗаказаноПокупателями) КАК |
ЗаказаноПокупателями, |
|
СУММАфложеннынЗапрос.ЗаказаноПоставщикам) КАК ИЗ |
ЗаказаноПосгавщикам |
|
(ВЫБРАТЬ |
|
|
ЗаказыПокунателейОстаткн. Номенклатура КАК Номенклатура. ЗаказыГІокупателейОстаі ки.КолнчествоОстаток КАК ЗаказаноПокупателями, |
0 КАК ЗаказаноПоставщикам
ИЗ |
|
|
РепістрН акоплен ии. Заказы Покупателей.Остатки* ЛДатаОтч,) |
КАК ЗаказыПокупателейОстатки
ОБЪЕДИНИТЬ
ВЫБРАТЬ
ЗаказыПоставщикамОстатки.Номенклатура,
0,
ЗаказыПоставщикамОстатки.КоличествоОстаток
ИЗ |
|
|
РспістрНакоплсния.Зака!ыПоставшикам.Остатки(&ДаіаОтч,) |
|
К А К Заказы П оставщн камОстатки |
|
|
) КАК ВложенныйЗапрос |
|
|
СГРУППИРОВАТЬ ПО |
|
|
ВложенныйЗапрос. Номенклатура |
|
Во вложенном запросе объединяем результаты запросов по остаткам в регистрах. Причем обеспечено, чтобы колонку «ЗаказаноПокупателями» формировали данные из регистра «ЗаказыПокупателей», а второй запрос в нее добавлял только нулевые значения. С колонкой «ЗаказаноПоставщикам» все с точностью до наоборот.
Соответственно на выходе вложенного запроса получится таблица из трех выходных полей, в каждой из записей которой будет информация по заказанному поставщикам или покупателям.
Чтобы свернуть эту таблицу - делаем запрос по таблице вложенного запроса и выполняем СГРУППИРОВАТЬ ПО по полю «Номенклатура», суммируя данные числовых колонок.
Как вывести некоторое значение вместо NULL взапросе?
Для этого можно использовать функцию языка запросов ECTbNULLQ, которая возвращает значение своего первого параметра в случае, если он не равен NULL, и значение второго параметра в противном случае:
ВЫВРАТЬ
ЕСТЫМ1ЛХ(Справочник. Номенклатура. Артикул, "—") КАК Артикул, Сііравочник.Номенклатура.Представление КАК Номенклатура
|
Артикул |
Номенклатура |
|
hH-150003 |
Ботинки мужские |
|
П-130002 |
Полусапожки на шнурках |
|
18009 |
Петр! |
|
Арт-88888 |
Сахарный песок |
|
Арт-4444 |
Юбилейное (печенье) |
|
Арт-8ЭЭЭЭ |
Крупа манная |
|
Арт-89000 |
Крупа гречневая |
|
|
Инвентарь |
|
|
Вилы |
|
|
Услуги |
|
|
Расходы на рекламу |
|
|
Расходы на ремонт |
|
|
Молочные |
Как вместе с данными некоторой таблицы получить общие итоги из этой же таблицы?
Например, требуется получить отчет о стоимости проданных товаров с демонстрацией процентной доли каждой номенклатурной позиции. Необходимо построить отчет следующего вида:
|
Номенклатура |
Сумма
продаж |
Процентная
доля |
|
Яблоки |
500 |
50 |
|
Груши |
350 |
35 |
|
Бананы |
100 |
10 |
|
Манго-манго |
50 |
5 |
Причем строки таблицы должны быть отсортированы по убыванию процентной доли.
Решение данной задачи может быть таким:
|
ВЫБРАТЬ |
|
|
ПролажиОбороты.Номенклатура КАК Номенклатура, ПродажиОбороты.СуммаОборот КАК СучмаПродаж. |
|
|
ПродажиОбороты.СуммаОборот / СовокунныеОбороты.СуммаОборот * 100 |
|
КАК ПроцентнаяДоля |
|
|
ИЗ |
|
|
РегиетрНакоплсння.Продажи.Обороты(&ДатаНач, &ДатаКон) |
КАК ПродажиОбороты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ |
|
|
РегистрНакопления.Иродажн.Обороты(&ДатаНач. &ДагаКон) |
|
КАК СовокупныеОбороты |
|
|
ПО ИСТИНА |
|
|
УПОРЯДОЧИТЬ по |
|
|
ПроцентнаяДоля УБЫВ |
|
Сами данные получаем из виртуальных таблиц «РегистрНакопления.Продажи.Обороты». При построении запроса сложностью является получение в каждой записи сразу и значения «СтоимостьОборот» конкретной номенклатурной позиции, и совокупного значения «СтоимостьОборот» по всем номенклатурным позициям.
Эта проблема решается посредством внутреннего соединения двух виртуальных таблиц «РегистрНакопления.Продажи.Обороты».
Поскольку от второй виртуальной таблицы берем только значение поля «СуммаОборот» (без разреза по номенклатуре), то совокупный оборот будет проставляться в соответствие каждой записи из первой виртуальной таблицы. Причем, поскольку соединение внутренне - то в случае, если продаж за период не было, не будет выводиться пустая запись.
Поле «ПроцентнаяДоля» каждой записи заполняется по формуле:
Процентная доля = СуммаПродаж/СовокупныйОборот * 100.
Далее производится сортировка, чтобы записи расположились по убыванию процентной доли.
Какполучить иерархические итоги по группе справочника?
Например, требуется выбрать номенклатуру вместе с остатками на складе из нужной группы справочника. Причем по группам остатки должны суммироваться.
|
Номенклатура |
Остатки на складе (шт) |
|
КОЛГОТКИ |
1120 |
|
Sanpellegrino |
420 |
|
Артикул 123456 (черные) |
120 |
|
Артикул 123457 (капучино) |
300 |
|
Sonata+ |
700 |
|
Артикул 773456 (черные) |
700 |
|
Артикул 774321 (черные) |
|
Требуется получить данные в виде таблицы следующего вида:
Оптимально по скорости данное действие выполняется при помощи запроса. Например, со следующим текстом:
ВЫБРАТЬ
ТоварыГруппы.Ссылка КАК Номенклатура,
ТоварыНаСкладахОстатки.КоличествоОстаток КАК КолнчествоОстаток ИЗ
(ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка ИЗ
Справочник.Номенклатура КАК Номенклатура ГДЕ
Номенклатура.Родитель В ИЕРАРХИИ(&Группа)
И
(Номенклатура.ЭтоГруппа = ЛОЖЬ)
) КАК ТоварыГруппы
ЛЕВОЕ СОЕДИНЕНИЕ
РегистрНакопления.ТоварыНаСкладах.Остатки(&МоментПолучения,
Номенклатура В ИЕРАРХИИ (&Группа))
КАК ТоварыНаСкладахОстатки
ПО ТоварыГ руппы.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
ИТОГИ СУММА(КоличествоОстаток) ПО Номенклатура ТОЛЬКО ИЕРАРХИЯ_
В данном запросе выполняется левое внешнее соединение двух таблиц.
Первая таблица получена вложенным запросом по таблице справочника с отсечением всех элементов, не входящих в требуемую группу и отсечением ее подгрупп.
Вторая таблица - виртуальная таблица остатков по регистру «ТоварыНаСкладах». Первым ее параметром будет впоследствии указан момент времени, на который нужно получить остатки. Второй обеспечивает отбор данных при построении виртуальной таблицы только по товарам, входящим в нужную группу.
Поскольку применяем левое внешнее соединение - результат будет содержать записи со всеми товарами, входящими в нужную группу.
Теперь добавляем промежуточные итоги только по группам, в которые входят попавшие в результат запроса элементы справочника.
Как по состоянию на заданную дату по регистру «ОстаткиНаСкладе» найти последний документ «ПоступлениеТоваровУслуг», по которому приходила номенклатура?
Сложность решения состоит в том, что из-за возможностей работать неоперативно, пользователь может формировать
«ПоступлениеТоваровУслуг» задним числом - это раз. Кроме того, в общем случае платформа позволяет формировать записи регистра с периодом, не совпадающим с датой документа..
Поэтому решать задачу следует ступенчато.
Сначала нужно найти по каждой номенклатурной позиции записи, сделанные документами «ПоступлениеТоваровУслуг» с максимальным на дату формирования отчета периодом.
Потом нужно будет найти регистраторы, породившие эти записи.
ВЫБРАТЬ
ВложснныйЗапрос. Номенклатура,
МАКСИМУМ(ТоварыМаСкладах.Регистратор) КАК Регистратор ИЗ
(ВЫБРАТЬ
ТоварыНаСкладах.Номенклатура КАК Номенклатура. МАКСИМУМ(ТоварыНаСкладах.Период) КАК Период ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах ГДЕ
ТоварыНаСкладах.Период <= «ЬДатаОтнета И
(ТоварыНаСкладах.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг)
СГРУППИРОВАТЬ ПО ТоварыНаСкладах.Номенклатура ) КАК ВложенныйЗапрос
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах ПО
ВложенныйЗапрос.Номенклатура = ТоварыНаСкладах.Номенклатура И
ВложенныйЗапрос. Период = ТоварыНаСкладах.Период ГДЕ
(ТоварыНаСклатах.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг;
СГРУППИРОВАТЬ по ВложеннынЗапрос. Номенклатура
Итак, вложенным запросом по таблице записей регистра «ТоварыНаСкладах» находим для каждой номенклатурной позиции значение периода записи, максимально близкой к «ДатаОтчета».
Источник - таблица записей регистра, выходные поля — «Номенклатура» и «Период». Применяем отбор по виду регистратора (посредством операнда ССЫЛКА будем брать только те записи, где регистратор входит в таблицу «Документ.ПоступлениеТоваровУслуг») и по периоду, не превышающему «ДатаОтчета». Потом применяем группирование по полю «Номенклатура» с определением максимально из значений поля «Период».
Результат вложенного запроса соединяем внутренним соединением по совпадению поля «Период» с таблицей записей регистра (для которой произведен отбор по виду регистратора) с тем, чтобы получить регистраторы из записей соответствующих периодов.
Поскольку существует вероятность наличия двух или более документов «ПоступлениеТоваровУслуг» сделавших движения в одном и том же периоде - то выбираем более поздний из них для каждой номенклатурной позиции за счет СГРУППИРОВАТЬ ПО (в общем -«...в живых должен остаться только один»).
Хочется сразу предупредить, что для случая значительного объема товародвижения время выполнения такого запроса может быть очень большим.
Если данную задачу необходимо решать за минимальное время - под нее лучше создать периодический регистр сведений «ПоследнийПриход» с измерением «Номенклатура» и ресурсом «ДокументПоступления». При проведении соответствующих документов делать движения по этому регистру. А отчет получать срезом последних на нужную дату. Поскольку записей в таком регистре будет на порядки меньше, нежели в одном из самых загруженных регистров конфигурации - скорость выполнения запроса возрастет существенно.
Как подсчитать количество записей с одинаковым значением некоторого поля?
Например, нужно построить счетчик элементов справочника «Контрагенты» по реквизиту «ОсновнойМенеджерПокупателя» и отсортировать его по убыванию.
У элементов справочника «Контрагенты» есть реквизит «ОсновнойМенеджерПокупателя» (тип значения
«СправочникСсылка.Пользователи»), В значения данного реквизита прописываются ссылки на менеджеров предприятия. Необходимо сформировать таблицу, в которой было бы видно, сколько контрагентов закреплено за тем или иным менеджером, причем в следующем порядке:
|
Основной |
Количество |
|
менеджер |
закрепленных |
|
покупателя |
покупателей |
|
Иванов |
33 |
|
Батов |
17 |
|
Семашко |
10 |
Лучше всего запросом:
ВЫБРАТЬ
Контрагенты.ОсновнойМенеджерПокупателя,
КОЛИЧЕСТВО(Контраі енты.Ссылка) КАК Количествозакрепленных ИЗ
Справочник.Контрагенты КАК Контрагенты ГДЕ
(Контрагенты.^ЗгоГруппа = ЛОЖЬ)
И
(Коитрагенты.ОсновнойМенеджсрПокупателя о &НсЗаполненМснеджер)
СГРУППИРОВАТЬ ПО Контрасенты.ОсновнойМенеджерПокупателя
УПОРЯДОЧИТЬ ПО Количествозакрепленных УБЫВ
Выходными полями таблицы запроса по справочнику «Контрагенты» делаем «ОсновнойМенеджерПокупателя» и «Ссылка».
Для того, чтобы группы не мешали нашей статистике - отбрасываем их. Кроме того, отбрасываем тех контрагентов, у которых не указан конкретный менеджер в реквизите «ОсновнойМенеджерПокупателя». Для этого параметру запроса «НеЗаполненМенеджер» нужно будет присвоить следующее значение:
Справочники. Пользователи. ПустаяСсылкаО
Поскольку самих контрагентов показывать не нужно - применяем СГРУППИРОВАТЬ ПО. Групповым полем будет
« Контрагенты. ОсновнойМенеджерПокупателя», суммируемым
«Контрагенты.Ссылка», функция КОЛИЧЕСТВО.
В результате получим уже свернутую (сжатую) по менеджерам таблицу.
Упорядочиваем ее записи по убыванию.
Как в итоговых записях вывести количество различных записей?
Например, требуется распечатать таблицу закрепленных за менеджерами покупателей с указанием их количества.
В отличие от предыдущего примера в результате запроса должны остаться покупатели, но и суммарное количество покупателей нужно тоже показывать:
|
Менеджер |
Покупатель |
Количество |
|
Иванов |
|
3 |
|
Иванов |
ООО «Лабан и Ко» |
1 |
|
Иванов |
ЗАО «Шустер и сыновья» |
1 |
|
Иванов |
Энигма Инк. |
1 |
|
Батов |
|
1 |
|
Батов |
Краски и Лаки |
1 |
Таблицу можно получить запросом с использованием ИТОГИ ПО.
ВЫБРАТЬ
Контратенты.ОсновнойМенеджерПокупателя.Представление КАК ОсновнойМенеджерПокупателя, Контрагенты.Прсдставление,
1 КАК КоличествоЗакрспленных ИЗ
Справочник.Контрагенты КАК Контрагенты ГДЕ
(Контрагенты.ЭтоГруппа = ЛОЖЬ)
УПОРЯДОЧИТЬ ПО КоличествоЗакрепленных УБЫВ
ИТОГИ КОЛИЧЕСТВО) КоличествоЗакрепленных) ПО ОсновнойМенеджерПокупателя
Источник - таблица «Справочник.Контрагенты». Посредством условия отбора отбрасываем записи групп справочника.
Поскольку результат запроса потом надо будет выводить на печать, в качестве выходных полей используем представление поля «ОсновнойМенеджерПокупателя» и представление самого элемента справочника, и поле «КоличествоЗакрепленных» для каждой записи (для уровня детальных записей заполняем его единичками).
Далее вводим промежуточные итоги по полю
«ОсновнойМенеджерПокупателя», суммируя значения поля « КоличествоЗакрепленных».
Кроме того, не забудем упорядочить результат по убыванию количества закрепленных.
Как узнать количество записей в результате запроса?
Проще всего это сделать посредством выборки результата.
Результат = Запрос.ВыполнитьО;
КолЗаписей - Результат.Выбрать(),Количество():
Метод Количество () возвращает количество записей в выборке.
Как проверить достаточность остатков товаров на складах, указанных в документе?
Например, требуется проверить достаточность остатков в регистре «ТоварыНаСкладах» по товарам и складам, указанным в табличной части «Товары» документа «ВнутреннийЗаказ».
Табличная часть «Товары» документа «ВнутреннийЗаказ» может заполняться пользователем вручную и иметь следующий вид:
Как в запросе осуществить отбор по значению перечисления?
Причем реквизит «Размещение» имеет составной тип
(ДокументСсылка.ЗаказПоставщику,
СправочникСсылка.Склады) а количество списываемого товара в базовых единицах должно определяться по формуле:
КоличествоСписываемогоТ овара = Количество* Коэффициент.
Регистр «ТоварыНаСкладах» имеет следующую структуру:
і
9 ТовврыНаСкладах Й-/ * Измерения —!. Склад —. Номенклатуре I. ХарактеристикаНоменклатурія . . СермяНомеиклатуры . Качество ?-|_ Ресурсы
*•—I Количество
Для проверки достаточности остатков желательно получить одним запросом таблицу вида:
|
Номенклатура |
Склад |
Количество |
Количество |
|
|
|
списываемое |
в остатке |
|
Минск-Атлант 126 |
Главный склад |
1 |
10 |
|
Минск-Атлант 712 |
Главный склад |
3 |
2 |
|
Стинол 101 |
Главный склад |
1 |
11 |
|
Bosh-675 |
Главный склад |
7 |
17 |
|
Минск-Атлант 712 |
Склад электротоваров |
1 |
1 |
Обратите внимание, в общем случае в табличной части документа может иметь место неоднократное указание какой-нибудь конкретной комбинация «Номенклатура-Склад» (в нашем случае «Минск-Атлант 712 - Главный склад»). В выходной таблице данные документа в таких случаях должны быть свернуты.
Поэтому запрос можно построить левым внешним соединением вложенного запроса по документу (группирующего данные из документа по номенклатуре и складу) и виртуальной таблицы «РегистрНакопления.ТоварыНаСкладах.Остатки»
ВЫБРАТЬ
ВложенныйЗапрос. Номенклатура. ВложенныйЗапрос.Размещение КАК Склад. ВложенныйЗапрос. КоличествоСписываемое,
Товары НаС кладахОстатки. Кол и чествоОстаток ИЗ
(ВЫБРАТЬ
ВнутреннийЗаказТовары.Номенклатура КАК Номенклатура, ВнутреннийЗаказТовары.Размещение КАК Размещение. СУММА(ВнутренннйЗаказТовары. Количество
¦ВнутренннйЗаказТовары. Коэффициент)
КАК КоличествоСписываемое
ИЗ
Документ. ВнутренннйЗаказ.Товары КАК ВнутреннийЗаказТовары ГДЕ
ВнутреннийЗаказТовары.Ссылка = &Ссылка
СГРУППИРОВАТЬ ПО ВнутреннийЗаказТовары.Номенклатура.
ВнутреннийЗаказТовары.Размещение ) КАК ВложенныйЗапрос
ЛЕВОЕ СОЕДИНЕНИЕ
РеіисірНакогшения.ТоварыНаСкладах.Остатки(&МоментВремениДокумента, Склад В (ВЫБРАТЬ РАЗЛИЧНЫЕ
ВЫРАЗИТЫВнутреннийЗаказТоварыДляОтбора. Размещение КАК Справочник.Склады)
ИЗ
Документ.ВнутреннийЗаказ.Товары
КАК ВнутреннийЗаказТоварыДляОі бора
ГДЕ
ВнутреннинЗаказТоварыДдяОтбора.Ссылка = &Ссылка И
НЕ ВЫРАЗИТЫВнутреннийЗаказТоварыДляОтбора.Размещение КАК Снравочннк.Склады) ЕСТЬ NULL )
И
Номенклатура В
(ВЫБРАТЬ РАЗЛИЧНЫЕ
ВнугреннийЗаказТоварыДляОтбора.Номенклатура
ИЗ
Доку мент. ВнутренннйЗаказ.Товары
КА К ВнутренннйЗаказТоварыДляОтбора
ГДЕ
ВнутреннийЗаказТоварыДляОтбора.Ссылка = &Ссылка)) КАК ТоварыНаСкладахОстатки НО
ВложенныйЗапрос. Номенклатура = ТоварыНаСкладахОстатки.Номенклатура И
ВложенныйЗапрос. Размещение = ТоварыНаСкладахОстатки.Склад
Немножко подробнее о параметрах виртуальной таблицы « РегистрНакопления. Товары НаСкладах. Остатки»:
Первым параметром должен передаваться момент времени документа. Момент времени - это тип данных, содержащий дату и ссылку на документ. Именно он позволяет однозначно позиционировать документ среди других, обладающих той же датой (дата ведь,, как известно, имеет точность - только до секунды). В результате мы получим данные об остатках именно на момент времени документа.
Вторым параметром передаем отбор по измерениям.
Для измерения «Склад» надо передать таблицу тех складов, которые встречались в табличной части нашего документа. Получаем ее вложенным запросом. Сложность в данном случае заключается в том, что тип значения реквизита «Размещение» - составной. А нам нужны только значения типа СпрЗВОЧНИкСсылка.Склад. Сложность разрешается применением Выразить(). В результате мы приводим данные к нужному типу значения, а значения NULL, которые «не привелись» -отсекаем условием. Кроме того, выбираем только не повторяющиеся записи.
Аналогично - для измерения «Номенклатура». В качестве таблицы для возможных значений отбора передаем таблицу номенклатурных позиций, полученную запросом по табличной части нашего же документа.
Осуществлять такие отборы на параметрах виртуальных таблиц важно для обеспечения быстроты получения виртуальной таблицы. Чтобы не получилось, что она строится по тем номенклатурным позициям и тем складам, которых и в документе-то и нет.
Само же соединение осуществляется по полям «Номенклатура» таблиц «ВложенныйЗапрос» и «ТоварыНаСкладахОстатки» и по полям «Размещение» и «Склад».
Как в запросе осуществить отбор по значению перечисления?
Необходимо отобрать всех работников предприятия, стоящих на момент «ДатаОтчета» на воинском учете. Данные о воинском учете данные хранятся в периодическом регистре сведений «ВоинскийУчет».
Ф ВоинскийУчет ? * . Измерения I—I. Физ/ыцо 0 _ Ресурсы
— 0 ОтношениеКВсимскойОбязаиности — I ОтнсзшениеКВсиеоюмуУчегту
— I Категория Запас а
— 0 Звание — I Состав -0 ВУС
— 0 Годность
— 0 Воемиэмат
— 0 НаличиеМоблренгысаиия
— 0 НомерКоманаьПарпы
I— 0 Забронировано реализацией 2 Реквизиты
Тип значения ресурса «ОтношениеКВоинскомуУчету» «ПеречислениеСсылка.ОтношениеКВоинскомуУчету».
Получить требуемое можно посредством запроса:
Запрос.Текст= "ВЫБРАТЬ I ВоинскнйУчетСрезПоследних.Физлицо |ИЗ
I Регистреведений.ВоинскийУчет.СрезПоследнихІ&ДатаОтчета)
КАК ВоинскийУчетСрезПоследних
I
ГДЕ
I ВоинскийУчетСрезПоследних.ОтношениеКВоинскомуУчету = &Состоит'
Источником является виртуальная таблица
«РегистрСведений.ВоинскийУчет.СрезПоследних», рассчитанная на дату, указываемую в параметре «ДатаОтчета».
В результате запроса получим таблицу физических лиц, удовлетворяющих условию отбора. Отбор производится по полю «ОтношениеКВоинскомуУчету».
Сами же значение параметров устанавливается следующим образом:
Запрос.Установить! Іараметр< "ДатаОтчета". ДатаОтчета): Запрос.УстановитьПараметрС'Состоит",
Перечнслення.ОтношениеКВоішскомуУчету. Состоит);
Как получить курсы валют на две интересующие даты?
Для получения данных используем запрос. Текст запроса приведен ниже:
ВЫБРАТЬ
ВалютыСрезПоследннх.Валюта,
ВалютыСрезПоследних.Курс,
&ПерваяДата Как Дата ИЗ
Регистреведений.Валюты.СрезПоследних(&ПерваяДата,) КАК ВалютыСрезПоследних
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ВалютыСрезПоследннх.Валюта,
ВалютыСрезПоследних.Курс,
& Вторая Дата ИЗ
Регистре ведений. Валюты.СрезПослелних(&ВтораяДата.) КАК ВалютыСрезПоследних
Фактически первый запрос получает курсы валют на первую, интересующую нас дату, второй на вторую. Для сортировки можно дополнительно описать раздел «Упорядочить».
Как одним запросом получить таблицу расхождений курсов взаиморасчетов всех выписанных документов «ЗаказПокупателя» с официальным курсом?
Необходимо получить таблицу следующего вида:
|
Документ |
Валюта
договора |
Курс
взаиморасче
тов |
Курс
официальный |
Превышение |
Заказ покупателя
ТК000007 от 05.08.2004 12:00:01 |
USD |
31,51 |
30,6691 |
0,8409 |
Заказ покупателя
ТК000003 от 26.07.2004 11:42:39 |
руб |
1 |
1 |
|
Заказ покупателя
ТК000023 от 26.09.2004 12:00:02 |
EUR |
33,42 |
33,1609 |
-2,74 |
В отличие от вышеприведенного примера, дат получения курсов у нас очень много (по числу документов).
В таком случае лучше поступить следующим образом:
ВЫБРАТЬ
ВложенныйЗапрос.Ссылка КАК Документ, ВложенныйЗапрос.ДоговорКонтраіеніаВалютаВзаиморасчетов КАК ВалютаДоговора, ВложенныйЗапрос.КурсВзаиморасчетов,
ВЫБОР
КОГДА КурсыВалют.Курс ЕСТЬ NULL ТОГДА О ИНАЧЕ
Курсы Валют. Курс КОНЕЦ КАК КурсОфициальный,
ВЫБОР
КОГДА КурсыВалют.Курс ЕСТЬ NULL ТОГДА ВложенныйЗапрос. Курс Взаиморасчетов ИНАЧЕ
ВложснныйЗапрос.КурсВзаиморасчетов - Курсы Валют. Курс КОНЕЦ КАК Превышение ИЗ
(ВЫБРАТЬ
ЗакачІ Іокупателя.Ссылка КАК Ссылка.
МАКСИМУМ(КурсыВалют.Период) КАК Период. ЗаказПокупагеля.КурсВчанчорасчстов КАК КурсВчаиморасчетов. ЗакачГІокупателя.ДоговорКонграі ента ВалюіаВчанморасчечов КАК ДоговорКончрагентаВаіютаВзаиморасчетов ИЗ
Докумснт.ЗакаіПокупагеля КАК ЗакачІІокупателя ЛЕВОЕ СОЕДИНЕНИЕ
РегистрСведений.КурсыВалют КАК КурсыВалют НО
ЗакачПокупателя.ДоговорКонтрагента.ВалютаВчаиморасчетов =
КурсыВалют.Валюта
И
ЗакачПокупателя.Дата >= КурсыВалют.Период
СГРУППИРОВАТЬ ПО ЗакачПокупателя.КурсВчаиморасчетов,
ЗакачПокупателя.ДоговорКоитраіента.ВалютаВчаиморасчетов.
ЗакачПоку пателя.Ссылка ) КАК ВложенныйЗапрос
ЛЕВОЕ СОЕДИНЕНИЕ
Рсгнс?рСведений.КурсыВачют КАК КурсыВалют ПО
ВложенныйЗапрос ДоговорКонтрагентаВа.чютзВчаиморасчетов =
КурсыВалют.Валюта
И
ВложенныйЗапрос.Период = КурсыВалют.Период
Во вложенном запросе получаем необходимые данные из документа и максимально близкий к дате документа период записи по такой же валюте из таблицы регистра сведений «КурсыВалюты».
Полученную таблицу внутренним соединением соединяем опять с таблицей регистра сведений «КурсыВалюты». Но теперь уже по совпадению полей «Валюта» и «Период». Из соответствующих этому совпадению записей получаем выходные поля, согласно требуемому.
Обратите внимание, может иметь место ситуация, когда дата документа меньше периода самой первой записи регистра. Предусмотрено, что в этом случае поле «КурсОфициальный» вернет нулевое значение, а поле «Превышение» курс взаиморасчетов.
Как написать запрос таким образом, чтобы на определенном уровне иерархии запроса считались одни итоговые функции, а на другом уровне другие?
Необходимо получить данные в следующем виде:
|
Номенклатура |
Характеристика |
Остаток |
Заказ |
Резерв |
|
Ботинки муж. |
Размер 45 |
10 |
|
8 |
|
Ботинки муж. |
Размер 45 |
10 |
|
|
|
Ботинки муж. |
Размер 45 |
|
Заказ**1 |
2 |
|
Ботинки муж. |
Размер 45 |
|
Заказ №2 |
6 |
|
Ботинки жен. |
Размер 38 |
5 |
|
2 |
|
Ботинки жен. |
Размер 38 |
5 |
|
|
|
Ботинки жен. |
Размер 38 |
|
Заказ №4 |
2 |
В самой базе данных данные находятся в регистрах накопления следующей структуры:
Остатки номенклатуры:

Остатки заказов покупателей:
? і« ЗакаэыПокупателем Измерения
— L. Догоеор?заиморасчетое ' . ЗакаэЛокулателя t. ТоварТара — t - Номенклатура — L ХарактеристикаНоме»*латуры В-Гя Ресурсы
Количество
Следует отметить, что в прямой постановке задача не решается. При определении раздела «Итоги» агрегатные функции итогов будут
считаться на всех уровнях иерархии запроса. Но постараться добиться подобного эффекта можно с помощью запроса:
ВЫБРАТЬ
ОстаткиТоваровКомпанииОстаткн.Номенклатура КАК Номенклатура. ОетаткнТоваровКомпанинОстатки. Номенклатура. Представление. ОстаткиТоваровКомпанииОстаткн. Хара ктеристикаНоменклатуры КАК ХарактсрпсіикаНомснклатуры,
ОстаткнТоваровКомпанинОстатки.Хара ктеристикаНоменклатуры. Представление, ОстаткиТоваровКомнанниОстаткн.КоличествоОстаток КАК КолнчествоОстаток, NULL как Закат.
О КАК Резерв ИЗ
РегистрНакопления.ОстаткиТоваровКомпанин.Остатки КАК ОстаткиТоваровКомпанииОстаткн
ОБЪЬДИНИТЬ ВСЕ
ВЫБРАТЬ
ЗаказыПокупателейОстатки. Номенклатура,
ЗаказыПокупателейОстаткн. Номенклатура. Представление. ЗаказыПокупателейОстатки. ХарактернстикаНоменклатуры, ЗаказыПокупателейОстатки.ХарактеристикаНоменклатуры.Представление.
О,
ЗаказыПокупателейОстатки.ЗаказПокупателя, ЗаказыПокупателейОстаткн.КоличествоОстаток ИЗ
Реі истрНакопления. Заказы Покупателей. Остатки КАК ЗаказыПокупателейОстатки
ИТОГИ СУММА(КоличествоОстаток), СУММА(Резерв) ПО Номенклатура,
ХарактернстикаНоменклатуры_
Первым запросам выбираются остатки, в полях соответствующих данным о резерве проставляем NULL и 0. Вторым запросом получаем данные по резервам. Раздел ИТОГИ позволяет внести иерархию в результат запроса с указанием остатка по позиции и итога по количеству зарезервированного товара.
Как получить перечень документов, приведших данные подчиненного периодического регистра сведений к определенному состоянию?
По данным периодического регистра сведений «КандидатыНаРаботу»
' КеноиаетьМаРаботу ф-^t-. Измерения
1—U Ф из Лицо ф~ f
a Ресурсы
L-1 Статус Оі Реквизиты |— — Оценке
— Подразделение — Должность
требуется построить таблицу:
|
ФизЛицо |
Документ |
Статус |
|
Андреева Жанна Юрьевна |
|
Отложен |
|
Андреева Жанна Юрьевна |
Регистрация кандидатов 000000
01 от 31.01.2004 0:00:00 |
Принят к рассмотр
ению |
|
Андреева Жанна Юрьевна |
Регистрация собеседования канд идата 00000005 от 09.02.2004 0:0 0:00 |
Отложен |
|
Арефьев Виталий Федорович |
|
Отложен |
|
Арефьев Виталий Федорович |
Регистрация кандидатов 000000
03 от 28.03.2004 0:00:00 |
Принят к рассмотр
ению |
|
Арефьев Виталий Федорович |
Регистрация собеседования канд идата 00000027 от 30.03.2004 0:0 0:00 |
Отложен |
На первом уровне таблица включать в себя указание всех кандидатов, для которых на момент формирования отчета статус приема на работу равен «отложен».
На втором уровне должны быть указаны все документы, выполнявшие движения по данным кандидатам с указанием устанавливаемого ими статуса.
Данную задачу лучше всего решить посредством запроса со следующим текстом:
ВЫБРАТЬ
КандидатыНаРаботу .ФизЛицо КАК ФизЛицо,
КандидатыНаРаботу.Регистрзтор КАК Документ.
КандидатыНаРаботу.Статус КАК Статус ИЗ
Регистре ведений. КандидатыНаРаботу.СрезІ1оследних(&ДатаОтчста.)
КАК Кандидаты НаРаботуСрезПоследних
ЛЕВОЕ СОЕДИНЕНИЕ
Регистреведений.КандидатыНаРаботу КАК КандидатыНаРаботу ПО
КандидатыНаРаботуСрезПоследних.ФнзЛицо = КандидатыНаРаботу .ФизЛицо ГДЕ
КандидатыНаРаботуСрезПоследних.Статус = &Отложен И КандидатыНаРаботу.Период <= &ДатаОтчета
УПОРЯДОЧИТЬ ПО
КандидатыНаРаботу. ФизЛицо. Наименование,
Документ
ИТОГИ МАКСИМУМ(Статус) ПО ФизЛицо
АВТОУПОРЯДОЧИВАНИЕ
В качестве источника будет таблица - результат внутреннего соединения виртуальной таблицы
«РегистрСведений.КандидатыНаРаботу.СрезПоследних», рассчитанной на момент формирования отчета и реальной таблицы записей регистра сведений «КандидатыНаРаботу» по полю «ФизЛицо».
В результате отбора останутся только записи, в которых значение поля «Статус» равно «Отложен» и где период записей меньше даты отчета.
Выходными полями назначаем те, что требовались при постановке задачи.
Запросы,отчеты
Как установить параметры запроса, если текст запроса заранее не известен?
Такая необходимость может возникнуть, когда текст запроса формируется динамически, в зависимости от некоторых установок, выбранных пользователем.
В этом случае можно воспользоваться методом запроса НаЙТиПараметры(), который возвращает коллекцию объектов ОписаниеПараметраЗапроса, содержащих имя и тип значения каждого параметра:
Запрос = Новый ЗапросС ІВЫБРАТЬ
I Номснклатура.Ссылка |ИЗ
I Справочник.Номенклатура КАК Номенклатура |ГДЕ
I Номенклатура.Ссылка В ИЕРАРХИІН&ГруппаНоменклатуры)’’);
// Получить описание параметров запроса.
ПараметрыЗапроеа = Запрос.НайтиПараметры();
Для Каждого ПараметрЗапроса Из ПараметрыЗапроеа Цикл ЗаданноеЗначение = Неопрелелено;
// Открыть диалог ввода значения данного параметра.
Если ВвестиЗначение(ЗаданноеЗначение,
"Задайте значение параметра " + ПарамегрЗапроса.Имя ПараметрЗапроса.ТипЗначения) Тогда Запрос.УстановитьПарачетр(ПараметрЗапроса.Нмя, ЗаданноеЗначение);
Иначе
Возврат;
КонецЕсли:
КонецЦикла;
РезультатЗапроса = Запрос.ВыполнитьО;
Анализ данных
® Как получить данные о товарах продаваемых вместе?
В ряде случаев необходимо получить данные о совместно продаваемых товарных позициях. Такая информация может учитываться представителями торгующих компаний при раскладке товаров на стендах и прилавках. Например, если такие товары будут находиться рядом, то этот факт может увеличить объем их совместных продаж.
Рассмотрим следующий фрагмент кода:
Анализ = Новый АналмзДанных;
// Выбранный тип анализа как раз и указывает на то, что ишем // «совместно продаваемые» товары.
Анализ.ТипАнализа = ТипС’АнализДанныхПоискАссоциаций");
Запрос = Новый Запрос:
Запрос.Текст = "ВЫЬРАТЬ
I ПродажнКомпанииОбороты.Регистратор Как ДокументПродажи,
I ПродажиКомпанниОбороты.Номенклатура |ИЗ
I РегистрНакопления.ПродажиКомпанни.ОборотьК&НачПериода,
&КонПериода,
Регистратор)
I КАК ПродажиКомпанниОбороты |УПОРЯДОЧИТЬ ПО ДокументПродажи”;
Запрос.УстановитьПараметрС'НачПериода", НачПериода); Запрос.УстановитьПараметрГ'КонПериода", КонПериода);
// Получить продажи за указанный период.
// Выбрана периодичность по Регистратору, т.к. необходимо получить // данные о совместных продажах в рамках одной покупки.
Анализ.ИсточникДанных = Запрос. ВыполнитьО;
II Выполнить анализ в соответствии с указанным источником. РезультатАнализа = Аналнз.ВыполнитьО;
//Для вывода результата анализа воспользуемся построителем // отчета анализа данных.
Построитель = Новый ПостроительОтчетаАнализаДанныхО: Построитель. Макет = Неоиределено;
|
Построитсль.Тнп Анализа = Тип("АнализДанныхПоискАсс< |
иіиаиии'); |
ТабДок = Новый ТабличныйДокумент;
Построитель.Вывести(РезультатАнализа, ТабДок);
ТабДок. Показать)); |
|
Результат анализа будет показан в открытом окне табличного документа. Следует обратить внимание на тот факт, что полученный таким образом анализ произведен исходя из значений параметров «по умолчанию». Значения таких параметров можно менять программно, либо через «связанный» элемент управления ТабличноеПоле. В общем случае состав и назначение параметров определяется видом анализа.
ф Как порекомендовать сопутствующие товары?
При покупке может возникнуть необходимость получения данных о том, чем данная покупка отличается от «среднестатистической» подобной покупки. Реализуем возможность получения рекомендаций покупателю исходя из соображения: «Обычно когда покупают закупленный вами перечень товаров, берут еще это...».
Рассмотрим фрагмент кода:
Анализ = Новый АналмзДанных:
// Найти ассоциации.
Анализ.ТипАнализа = ТнпС'АнализДанныхПоиск Ассоциаций");
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
I ПродажиКомпанниОбороты.Ретистратор КАК Доку мет Продажи
I ПродажнКомпанииОбороты.Номенклатура
|ИЗ
I РегистрНакоплення.ПродажиКомпании.Обороты(&НачПериода,
&Кон Периода, Регисіратор)
I КАК ПродажнКомпанииОбороты ІУПОРЯДОЧИТЬ ПО ДокумснтПродажи";
// Ассоциации ищем подокументно, это определяется поведением //объекта «АналнзДанных» «по умолчанию» при выборе // периодичности виртуадьной таблицы Регистратор
Запрос.УстаиовитьПараметрГ'НачПериода", НачПериода).
Запрос.УстановитьПараметрС'КонПериода", КонПсриода);
Анализ данных
Анализ.ИсточникДанных = Запрос.ВыполнитьО:
РезультатАнализа = Анализ.Выполнить();
// Исходя из полученного анализа создать прогноз.
МодельПрогноза = РезультатАнализа.СоздатьМодельПроі ноза();
// ТЗ- таблица значений, содержащая данные о том.
// какие номенклатурные позиции вошли в "текущую" покупку. МодельПрогноза.ИсточникДанных = ТЗ;
// ТП - элемент управления "Табличное поле" связанный через // свойство "Данные" с реквизитом формы "ТП“ (тип ТаблицаЗначений) ТП = МодельПрогноза.ВыполнитьО;
Элементы Формы.ТП.СоздатьКолонкиО:
В результате выполнения фрагмента кода «рекомендации» будут отображены в табличном поле «ТП». Следует помнить, о том, что в данном примере, что прогноз произведен исходя из значений параметров «по умолчанию». В общем случае состав и назначение параметров определяется видом анализа.
ф Как посмотреть, что будет покупаться в дальнейшем?
Необходимо решить следующую задачу: если клиент приобрел какой-либо товар, то с определенной долей вероятности он может прийти еще за каким-то дополнительным товаром. (Например, после покупки принтера он может приходить за расходными материалами к нему). Как получить подобную информацию?
Рассмотрим следующий фрагмент кода:
ТабДок = Новый ТабличныйДокумент:
Анализ = Новый АналнзДанных;
// Нужно спрогнозировать цепочку событий, поэтому выбираем // тип анализа «Поиск последовательностей».
Анализ.Тип Анализа = ТмпГАнализДанныхПоискПоследователыіостей");
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
I ПродажиКомпанииОбороты.ДоговорВзаиморасчетовПокупателя. Владелец I КАК Контрагент,
I ПродажиКомпанииОбороты. Номенклатура,
I ПродажиКомпанииОбороты.Период |ИЗ
I РегистрНакопления.ПродажиКомпании.Обороты(&НачПериода.
&КонІ Іериода,
Регистратор)
КАК ПролажиКомпанииОбороты";
Запрос.УстановитьПараметр("НачПериода", НачПериода); Запрос.УстановнтьІІараметрС’КонПериода", КонПериода);
А и ал и). И сточи и к Д а н н ых = Запрос.ВыполннтьО:
Колонка = Анализ.НастройкаКолонок.НайтиС'Пернод");
//Указать, что колонка «Период» имеет тип «Время»,
// что «позволит понять» хронологию событий
Колонка.ТипКолонки = Тип Колонки АнализаДаниыхІ Іоиск Последовательностей .Время:
РезультатАнализа = Аналнз.ВыполнитьО;
МодельПрогноза = РезулыатАнализа.СоздатьМодельПрогнозаО;
// ТЗ- таблица значений, содержащая исходные данные для прогноза // например, какой контрагент, какой товар закупил (исходя из чего // попытаемся узнать, что они еще закупят).
МодсльПрогноза.ИсточникДанных = ТЗ;
// ТП - элемент управления «Табличное поле» связанный через //свойство «Данные» с реквизитом формы «ТП»
//(тип ТаблицаЗначений)
ТП = МодельПрогноза. ВыполнитьО:
ЭлементыФормы.ТП.СоздатьКолонкиО;
// Построитель - реквизит формы, имеющий тип // ПостроительОтчетаАнализаДанных. Ряд табличных полей // в диалоге могут быть связаны со свойствами-коллекциями // данного объекта
Построитсль.ТипАнализа = ТипС'АнализДанныхГІоискПослсдователыіостей''):
Построитель.Вывестн( РезультатАнализа. ТабДок);
ТабДок.ПоказатьО;
Полученные данные (что клиенты еще будут приобретать дополнительно исходя из уже совершенных ими покупок) можно использовать, например, при анализе складских запасов.
Представление результатов отчетов
Табличный документ, текстовый документ
Как вывести результат запроса в табличный документ?
Наиболее эффективным способом решения этой задачи является использование построителя отчета.
Однако в некоторых случаях требуется более «тонкая» работа с макетом табличного документа и тогда формирование результирующего табличного документа необходиомо выполнять самостоятельно, без использования возможностей построителя отчета.
Предварительно создадим макет (тип макета «Табличный документ»). Внешний вид макета приведен на рисунке. Имя макета: «Макет».

Текст процедуры, в которой формируется запрос, и результат запроса выводится в табличный документ, приведен ниже:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
I ОстаткиТоваровКомпанииОстатки.СкладКомпанни КАК СкладКомпанииСсылка, I ОстаткиТоваровКомпанииОстатки.Номенклатура КАК НоменклатураСсылка.
I СУММА(ОстаткиТоваровКомманииОстатки.КоличествоОстаток) КАК Остаток,
I ОстаткиТоваровКомпанииОстатки.Номенклатура.Представление КАК Номенклатура,
I ОстаткиТоваровКомпанииОстатки.СкладКомпании.Представление КАК Склад |ИЗ
I РегистрНакопления.ОстаткиТоваровКомпанин.Остатки(&Момент)
КАК ОстаткиТоваровКомпанииОстатки
|СГРУППИРОВАТЬ ПО
I ОстаткиТоваровКомпанииОстатки.СкладКомпанииСсылка,
I ОстаткиТоваровКомпанииОстаткн.НоменклатураСсылка
|ИТОГИ СУММА(Остаток) ПО Общие,
I Склад";
Запрос.УстановитьПараметрС'Момент", Неопределено);
Результат = Запрос.ВыполнитьО;
// Получить поле табличного документа, в которое будем выводить результат. ТабДок = ЭлементыФормы.ПолеТаблнчногоДокумента;
// Очистить данные в табличном документе // (возможно данные уже выводились ранее).
ТабДок.Очистить!);
Макет = ПолучитьМакетС'Макет");
// Получить именованные области из макета.
ОбластьОбщийИтог = Макег.ПолучитьОбласть("ОбщийИтог");
ОбластьСклад = Макет.ПолучитьОбластьС'Склад");
ОбластьНоменклатура = Макет.ПолучитьОбластьІ "Номенклатура");
// Получить выборку по первой итоговой группировке (первый уровень). ВыборкаОбшийИтог = Результат
.Выбрать!ОбходРезультатаЗапроса.ПоГруппнровкам);
// Запись общего итога всегда одна, поэтому можно обойтись без организации цикла. ВыборкаОбшийИтог.СледующийО;
// Произвести запись данных из полей выборки в именованные // области с совпадающими именами.
ОбластьОбщийНтог.Парамстры.Заполнить(ВыборкаОбщийИтог);
// Включить область с заполненными параметрами в табличный документ.
ТабДок. ВывестиЮбластьОбщийИтог):
// "От" записи первого уровня получить подчиненную выборку // записей второго уровня (по итоговой группировке "Склад").
ВыборкаПоСкладу = ВыборкаОбшийИтог
.Выбрать(Об.\одРезультатаЗаироса.ПоГруппировкам);
Пока ВыборкаПоСкладу.СледующийО Цикл ОбластьСклад. Параметры.Заполнить! ВыборкаПоСкладу); ТабДок.Вывести(ОбластьСклад);

// Получить подчиненную выборку, содержащую детальные записи ВыборкаПоНоменклатуре = ВыборкаПоСкладу.Выбрать!);
Пока ВыборкаПоНомеиклатуре.Следующийі) Цикл ОбластьНоменклатура.ІІараметры.ЗаполннтыВыборкаПоНоменклатуре): ТабДок.Вывести(ОбластьНоменклатура);
КонецЦикла;
КонецЦнкла;
Следует сделать несколько замечаний к приведенному тексту.
В полях выборки результата запроса получаются представления ссылочных полей «Склад» и «Номенклатура». Получение представлений необходимо для вывода их в табличный документ. В противном случае, если бы в табличный документ выводились не представления ссылочных полей, а сами ссылки, выполнялись бы неявные запросы к базе данных для получения представления ссылочных значений, что привело бы к замедлению вывода отчета.
После выполнения запроса в переменную «ТабДок» получается расположенный в форме элемент управления
ПолеТабличногоДокумента, в который и будет осуществляться вывод результата отчета.
Результат запроса обходится по группировкам, в нескольких вложенных циклах. Сначала выбирается группировка верхнего уровня, содержащая запись общих итогов. Затем в цикле обходится группировка «Склад», и для каждого значения выборки этой группировки также во вложенном цикле перебираются детальные записи результата запроса.
Как вывести данные в табличный документ с возможностью сворачивания и разворачивания данных по группировкам?
Вывод данных в табличный документ рассмотрен в примере «Как вывести результат запроса в табличный документ?» на странице 257. Рассмотрим особенность организации группировок (в нашем примере: группировок строк, хотя можно группировать и колонки).
|
// Перед выводом данных в табличный документ используеі ТабДок. ИачатьАвтогруппировкуСтрокО; |
ся метод: |
|
// Выести область с указанием уровня. |
|
|
ТабДок.Вывестн(ОбластьОбщийИтог. ВыборкаОбщнйИтог |
УровеньО); |
// В конце работы с табличным документом необходимо выі // следующий метод:
ТабДок.ЗакончитьАвтогруппировкуСтрокО: |
ЮЛНИТЬ |
Перед выводом данных в табличный документ используется метод табличного документа НачатьАвтогруппировкуСтрок(), который автоматически создает группировки в табличном документе в соответствии со значением уровня строк, задаваемым при их выводе вторым параметром метода Вывести().
Следует отметить, что для определения группировок не обязательно это делать через автогруппировку. Для группировки строк можно использовать методы табличного документа НачатьГруппуСтрок() и ЗакончитьГруппуСтрок() (аналогичные методы существуют и для группировки колонок табличного документа).
Как при выводе данных в табличный документ свернуть все выводимые группировки?
Необходимо при выводе данных в табличный документ в развернутом виде оставить только группировки нулевого и первого уровней, а группировки более низких уровней отобразить в свернутом состоянии:
УровеньГруппировки = 1; //содержит индекс, с нуля ТабДок.Закончить Автогру ш іировкуСтрок();
ТабДок. ПоказатьУровеньГруипиро во кСтрок(УровеньГрупиировки);
В переменной «УровеньГруппировки» определяется уровень, до которого необходимо раскрыть группировки в табличном документе.
Как при выводе данных в табличный документ произвольно определить состав свернутых и развернутых группировок?
При выводе данных по заранее известным правилам, необходимо отображать какие-либо группировки в свернутом состоянии, какие-то - в развернутом. Допускается, что свернутые и развернутые группировки могут находиться на одном уровне.
ТабДок.Вывсс і ЩОб.'іаеі ьНоменкаа тура.
ВыборкаПоНоменклатуре.УровеньО,
Ложь);
Установка четвертого параметра метода Выбратъ() в значение Ложь приведет к тому, что данная область будет отображаться в свернутом виде.
ф Как выгрузить результат запроса с показом иерархии?
В форме расположено табличное поле с именем ТП. Тип значения табличного поля - ДеревоЗначениЙ. Необходимо в табличном поле показать результат выполнения запроса с показом иерархии данных.
Для реализации этой задачи необходимо написать текст запроса, который в обязательном порядке должен содержать раздел ИТОГИ (именно этот раздел определяет иерархию). В процедуре, отвечающей за заполнение данными табличного поля необходимо разместить следующие строки:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
I ПродажиКомпанииОбороты.Номенклатура КАК Номенклатура,
I ПродажиКомпанииОбороты.КолнчествоОборот КАК КолнчествоОборот |ИЗ
I РеінстрНакоиления.ПродажиКомпании.Обороты(&НачПернода. &КонПериода,, ) I КАК ПродажиКомпанииОбороты
ІИТОГІІ СУММА(КоличсствоОборот) ІЮ_
I Номенклатура ИЕРАРХИЯ";
Запрос.УстановитьПарамстрС’І ІачПериода", НачПериода); Запрос.УсгановитьПараметр<"КонГ1ериода”. КонПсриода);
Результат = Запрос. ВмполнитьО;
ЭлементыФормы.ТП.Значение = Результат
.Выгрузить(ОбходРезультатаЗапроса .ПоГ руппиронкам):
// Осуществить выгрузку с сохранением иерархии. ЭлсментыФормы.ТП.СоздатьКолонкиО:
Метод СоздатьКолонки() элемента управления ТабличноеПоле
удаляет ранее существовавшие колонки и создает новые в соответствии с новым источником данных.
® Где и как можно увидеть макет, автоматически генерируемый построителем отчета?
Поскольку тип значения свойства Макет построителя отчета -ТабличныйДокумент, то, как и всякий табличный документ, - его можно вывести на экран при помощи метода Показать():
ІіостроительОтчета. Макет = Неопределено: I ІостроитсльОтчета.Макеі НоказатЫ)
В данном примере имя построителя отчета было «ПостроительОтчета». Разумеется, данный код можно писать после того, как построитель отчета сформирован.
Первая строка кода - с присвоением свойству Макет значения Неопределено нужно только в тех случаях, когда мы точно хотим получить именно автоматически генерируемый построителем отчета макет. Дело в том, что до нашего кода построителю мог быть назначен другой макет, или он был изменен.
ф Как из построителя отчета передать данные в сводную таблицу?
В форме отчета есть табличный документ «ДокументРезультат», в его составе встроенная таблица «СводнаяТаблица». Необходимо обеспечить ее автоматическое заполнение по данным построителя отчета «ПостроительОтчетаОтчет».
После формирования построителя отчета можно сделать следующее:
ЭлементыФорчы
.ДокументРезультат
.ВстроенныеТаблицы
.СводнаяТаблица
.ИсточникДанных = ПостроительОтчетаОтчет:
ЭлементыФормы ¦ДокументРезультат ¦ ВстроенныеТаблицы ¦СводнаяТаблица ¦ОтображатьПоля = Истина;
Сначала указываем сам построитель отчета сводной таблице в качестве источника данных. Далее установкой свойства «ОтображатьПоля» вызываем на экран окно для интерактивного управления полями сводной таблицы.
Хочется подчеркнуть, что источником данных для сводной таблицы может быть не только построитель отчета, но и результат запроса.
Отчет формируется построителем отчета. Как убрать одну из колонок, поместив ее данные в расшифровку другой?
По документам «РегистрацияСобеседованияКандидата»:
РегмстрацияСобеседовамияКамаиаата 0 г Реквизиты
І.....- Ответственна
г — Контент арий
- ДатеСобеседоееимя
— - ВремяСобеседовения
— - ФизЛицо
— - Подразделение
— - Должность
[— - РезупьтатСобеседоваммя
- Помешение
— - РезюмеСобеседоваиия
Факт
—=-5і Т абли^ые чести
необходимо построить отчет по форме:
|
Кандидат |
Результат |
|
Абрамов Андрей Алексеевич |
Отклонен |
|
Аввакумов Алексей Аркадьевич |
Предложили работать |
|
Алексеев Вадим Юрьевич |
Отклонен |
|
Андреева Жанна Юрьевна |
Отложен |
Кандидаты должны располагаться в алфавитном порядке.
Причем при двойном клике по любому «результату» должен открываться сам документ, в котором данный результат был зафиксирован.
Данную задачу можно решить посредством следующей процедуры:
Процедура АлфавнтныйПереченьКандидатовСРасшифровкойО
ПостроительОгчета = Новый ПостроительОтчета:
ПостроительОтчета.Текст ="ВЫБРАТЬ
I РегисграцияС'обсседованияКандидата.ФнзЛиио КАК Кандидат.
I РегистрацняСобеесдованняКандидата.РезультатСобеседования КАК Результат.
I РегистрацияСобеседованияКандидата.Ссылка
|ИЗ
I Документ.РегиетрацияСобеседованияКандидата КАК РегнстрацияСобеседованияКандидата
ІУПОРЯДОЧИТЬ по
I РегистрацияСобеседованияКандндата.ФизЛицо. Наименование";
ПостронтсльОтчета.ВыполнитьО;
Макет = ПостроительОтчета.Макет:
// Очистить области, связанные с ссылкой.
ТекущаяОбласть = Неопределено;
Пока Истина Цикл
ТекущаяОбласть = Макет.НайтиТекст(”Ссылка”,
Т еку щаяОбласть.
Макет.ОбластьО);
Если ТекущаяОбласть = Неопределено Тогда Прервать;
Иначе
ТскущаяОбласть.ОчиститМ Истина. Истина, Истина);
КонецЕсли:
КонецЦнкла;
И Заполнить параметр расшифровки для областей, где параметр = "Результат". ТекущаяОбласть = Неопределено;
Пока Истина Цикл ТекущаяОбласть = Макет
.НайтиТекстІ "Результат". ТекущаяОбласть, Макет.ОбластьО);
Если ТекущаяОбласгь = Неопределено Тогда Прервать;
Иначе
Если ТекущаяОбласть.Параметр = "Результат" Тогда ТекущаяОбласть.ПараметрРасшифровки = "Ссылка";
КонецЕсли;
КонецЕсли;
КонецЦнкла;
ПостроительОтчета.Макет = Макет:
ПостроительОтчета. ВывестиО;
КонецПроцедуры_
Используем объект ПостроительОтчета. Текст запроса позволяет получить из таблицы документов
«РегастрацияСобеседованияКандидата» данные о кандидате, результате и ссылке на документ, в которой были зарегистрированы эти данные.
Далее построитель отчета выполняет указанный текст запроса.
Поскольку в выходной форме табличного документа колонок должно быть две - исправим макет построителя отчета.
Для этого считываем на переменную «Макет» макет, автоматический генерируемый построителем отчета.
Далее открываем цикл перебора областей ячеек макета, в которых присутствует текст «ссылка». Метод области ячеек табличного документа «Очистить()>> позволяет за счет своих параметров добиться очистки текста, формата и рамок области. Каждую найденную область - очищаем полностью.
Далее открываем цикл перебора областей ячеек табличного документа «Макет», где присутствует текст «Результат». Если в найденной области еще и параметр установлен, как «Результат» - значит именно в этой области нам нужно установить значение «ПараметрРасшифровки» как «Ссылка». Таким образом, мы обеспечим размещение содержимого полей «Ссылка» результата построителя отчета в расшифровки ячеек отображения полей «Результат» при формировании табличного документа по исправленному макету.
Остается только назначить построителю отчета исправленный макет и вывести построитель отчета.
Как сохранить настройки построителя отчета до следующего открытия формы отчета?
Допустим, необходимо сохранить настройки построителя отчета «П остроительОтчета».
Для этого нужно в обработчике события При закрытии формы вписать команду на сохранение значения настроек. Например, так:
СохранитьЗначение("НастройкаПостроителяДляОтчетаПродажи' + МстаданныеОИмя.
ПостроительО гнета. ПолучитьНастройкиО);
Первым параметром указано имя сохраняемого значения. Вторым -само сохраняемое значение. Поскольку метод сохраняет значение индивидуально для пары «ИнформационнаяБаза - Пользователь», то уникальность имени сохраняемого значения обеспечиваем за счет его формирования. Например, из имени отчета и имени формы.
При открытии данной же формы, для того, чтобы «вернуть» построителю отчета его настройки - можно будет сделать следующее:
// До установки настроек они ранее должны были быть таполнены И по тексту таироса.
ПостроительОтчета.ЗаполнитьНастройки():
И Установить настройки построителя отчета.
Настройка = ВосстановнтьЗначсниеС'НастройкаПостронтеляДляОтчетаПродажи"
+ МетаданныеО.Имя);
Если Настройка о Неопределено Тогда
ПостроительОтчета.УстановитьНастройки(Нас тройка):
КонецЕсли;
Восстанавливаем (сохраненное при окончании предыдущего сеанса работы с формой) значение настроек - по соответствующему имени значения.
Убедившись, что восстановить значение настроек действительно удалось - устанавливаем эти настройки для построителя отчета.
Как организовать показ примечаний в формируемом табличном документе?
По данным документов «Событие»:
~ Событие ? « Реквизиты
.....— АаресЗ лектроннойЛ очты
— - Важность
- ВиаОбъекта
— - ВииСобыгия
-- ВремяНапомм«ания
- Исто^икИнформецииПриОбрешеиии
- Комментарии
- Контактное Лицо .....- Контрагент
.....— Напот-емтьОСобьты
.....— НачалоСобытия
.....— ОкоичаниеСобытия
— - ОписатыеСобытия —— Основание
— - Ответответный —- Проект
— — СоцержаниеСобытия
— - СостоямиеСобытия —• Т ипСобытия
0 5:* Табличные части Й-liI СторокмиеЛмца
необходимо вывести информацию о зарегистрированных за период событиях по следующей форме:
|
ІОтветствеитІДата |
ВіиСобыпи |
Контрагент |
ОпткаимеСо4ытмя |
Федоров
(адмитыстр
втор) |
09102004
1647:00 |
Почтовое
гьсьмо |
Белявский-част мое лицо |
Просьба отослать ^
текст договора |
Федоров
гадмимістр
втор) |
03102004
165900 |
ТЪтчмая встреча |
Инвема |
Fw Установка
контактов с
контрагентом |
Федоров
(адкаеатстр |
28 09 2004 Г?чная встреча 121636 |
Алхимов АЛ |
Поговорить 0 '
продлении договора иа следующей год |
Федоров
(адьынистр
втор) |
28 09 2004 Телефотеа** 120002 звонок |
Свергуметжо |
Пет>вичт«)й звонок ' клиента |
Как видите, в колонке «ОписаниеСобытия» в некоторых ячейках установлены примечания, содержащие «СодержаниеСобытия»
Для формирования подобного табличного документа потребуется макет «Отчет» по следующей форме
|
Огысание |
|
|
^ = ОписаниеСобытия |
|
|
|
. |
2 1 3 1 4 1 S 1 « |
|
За го по в о* |
1 |
|
|
|
2 |
Состоявшиеся события (кратко) |
|
|
3 |
<Период с [ДатаНач] по [ДатаКон]> |
|
|
4 |
|
|
|
ШалкаТабп |
5 |
|
нтвекіпснныіІДла Віи' ооиііи | Контрагент ІОткаммеСооытмя |
|
Дета/ы |
< |
|
«Ответственны«Дата» «?идСобытмя» «Коитрагемт^кОг»«са»*іеСобытмя» |
|
ПодвапТаб |
7 |
|
|
|
Подвал |
8 |
|
|
|
|
О |
Обратите внимание, ячейка, содержащая «ОписаниеСобытия» -поименована («Описание»).
Сам же табличный документ будет формироваться следующей процедурой:
Процедура Отчет(ДатаНач, ДатаКон) Экспорт
Запрос = Новый Запрос;
// Сбор данных.
Запрос.Текст =
"ВЫБРАТЬ
I Событие.Ответственный КАК Ответственный,
I СобытиеДата.
I Событие.ВидСобытия.
I Событис.Контрагент,
I Событие.СодержаниеСобытия.
I Событие.ОписанисСобытня |ИЗ
I Документ.Событие КАК Событие |ГДЕ
I СобытиеДата МЕЖДУ &ДатаНач И &ДатаКон
I И
I (Событие.Проведен)
I И
I Событие.СостояниеСобытия = &Завершено
I
(УПОРЯДОЧИТЬ по I Ответственный";
Запрос.УстановитьПарамегрС'ДатаКон”, ДатаКон); Запрос.УстановитьПараметрСДатаНач", ДатаНач); Запрос.УстановитьПараметр( "Завершено".
Перечисления.СостоянияСобытий.Завершено)
Результат = Запрос.Выполнить():
// Сформировать табличный документ.
Макет = ПолучитьМакетСОтчет");
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок”); ОбластьШапкаТаблнцы = Макет. ПолучитьОбластьСШаикзТаблицы”): ОбластьДетальныхЗаписсй = Макет.ПолучитьОбластьСДегали");
ТабДок = Новый ТабличныйДокумент;
ОбластьЗаголовок.І1араметры.ДатаНач = ДатаНач;
ОбластьЗаголовок. ІІарамстры.ДатаКон = ДатаКон;
ТабДок.Вывести(ОбластьЗа головок);
ТабДок. Вывести(ОбластьШапкаТаблицы);
ВыборкаДетали = Результат.Выбрать();
Пока ВыборкаДетали.СледующнйО Цикл ОбластьДетальныхЗаписей.Параметры.Заполнить(ВыборкаДетали); ОбластьДетальныхЗаписей.Область("Описание'').Примечание.Текст =
ВыборкаДетаіи.СодержаниеСобытия ТабДок. Вывести(ОбластьДетальныхЗапнсей);
КонецЦикла;
ТабДок.ПоказатьО;
КонецПроцедуры
Выполняем запрос для получения всех необходимых данных по записям таблицы документа «Событие», которые удовлетворяют условиям отбора: документы проведены, их дата находится в интервале формирования отчета и значение реквизита «СостояниеСобытия» равно Завершено (тип значения
ПеречислениеСсылка.СостоянияСобытий).
Далее работа идет по выводу результата запроса в табличный документ.
Получаем макет. Из макета получаем необходимые для работы области.
Создаем табличный документ «ТабДок». Устанавливаем параметры области «Заголовок» и выводим ее в табличный документ «ТабДок».
Выводим область шапки таблицы.
Далее открываем цикл выборки из результата запроса.
Внутри цикла:
Заполняем параметры области детальных записей данными из одноименных полей строки выборки по результату запроса.
А в область «Описание» области детальных записей добавляем примечание. В качестве текста примечания указываем данные из поля «СодержаниеСобытия» выборки результата запроса.
Выводим очередную область детальных записей в «ТабДок».
По окончании цикла показываем сформированный табличный документ пользователю.
ф Как обеспечить, чтобы при вводе на печать не печатались первая колонка и первая строка табличногодокумента «ДокументРезультат»?
Для решения этой задачи лучше всего воспользоваться свойством табличного документа ОбластьПечати. После того, как табличный документ «ДокументРезультат» сформирован, пишем:
Доку мснтРезультат.Обласі ьі Іечати = ДокументРезультат
.Область(2,
2,
ДокументРезультат. ВысотаТаблицы, Документ Результат.ШирннаТаблицы
);
В качестве комментария: свойству ОбластьПечати необходимо передать область ячеек табличного документа, которую будем выводить на печать.
Для определения этой области указываем прямоугольную область, начинающуюся со 2-ой строки, 2-го столбца, и заканчивающуюся последней строкой табличного документа (ее номер определяем из свойства табличного документа ВысотаТаблицы) и последним столбцом (его номер определяем из свойства табличного документа
ШиринаТаблицы).
ф Как обеспечить фиксацию верхней части табличного документа, генерируемого построителем отчета, по срезу шапки таблицы?
Если макет автоматически генерируется построителем отчета можно воспользоваться тем, что в его составе есть область «ШапкаТаблицы» и следовать она будет сразу после области «Заголовок». Значит низ области «ШапкаТаблицы» как раз и будет границей желаемой области фиксации.
Например, построитель отчета называется «ПостроительОтчета», а табличный документ «ДокументРезультат».
Тогда после вывода построителя отчета в табличный документ можно сделать следующее:
ДокументРезультат.ФиксацияСверху = ПостроительОтчета
.Макет
.Области
.ШапкаТаблицы
.Низ;
То есть, устанавливаем значение свойства ФиксацияСверху табличного документа как номер нижней строки области «ШапкаТаблицы» макета табличного документа.
© Табличный документ формируется построителем отчета. Как при печати табличного документа обеспечить вывод шапки таблицы на каждой странице?
Если табличный документ строится по макету, сгенерированному построителем отчета, то в его составе будет область «ШапкаТаблицы».
Если табличный документ называется «ДокументРезультат», а построитель отчета - «ПостроительОтчета», после вывода построителя отчета в табличный документ можно сделать следующее:
ОбластьШапкн = ПостроительОтчета.Макет.Области. ШапкаТаблицы: ДокументРезультат.ПовторятьПриПечатиСтроки =
ДокументРезультат.Область(ОбластьШапки.Верх,. ОбластьШапки.Низ):
В свойство ПовторятъПриПечатиСтроки табличного документа достаточно передать любую область ячеек табличного документа, и она станет повторяться в каждом печатаемом листе.
В нашем случае данную область определили по координатам области «ШапкаТаблицы» автоматически генерируемого построителем отчета макета.
ф Как при выводе на печать «длинного» документа указать в колонтитулах страниц номер документа, дату и номер страницы?
Работа должна вестись со свойством ВерхниЙКолониіул табличного документа. Тип значения его объект
Колонтитул ТабличногоДокумента.
ТабДокумент.ВерхнийКолонтитул. Выводить = Истина; ТабДокумент.ВсрхнийКолонтитул.НачальнаяСтраница = 2; ТабДокумент.ВерхнийКолонтитул.ТекстСлева = Метаданные().Представление() +
" № ’ +
Номер;
ТабДокумент.ВерхнийКолонтитул.ТекстСтірава = "|&НомерСтраницы|";
Устанавливаем для нужного колонтитула признак вывода на печать. Далее указываем, что начинать вывод колонтитула следует не с первой страницы (по умолчанию), а со страницы № 2.
Передаем значения для заполнения свойств ТекстСлева и ТекстСправа. Обратите внимание, что типы значений этих свойств -Строка. В текст слева выводим представление и номер документа. В текст справа выводим номер текущей страницы.
ф Табличный документ формируется по макету, автоматически генерируемому построителем отчета. Как задать ориентацию страницы при печати?
Ориентация страницы в любом случае задается уже для самого табличного документа.
ПостроительОгчета.Вывести(ДокумеитРезультат);
ДокументРезультат.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт:
В данном примере свойству ОриентацияСтраницы табличного документа «ДокументРезультат» назначается значение Ландшафт системного перечисления ОриентацияСтраницы.
Табличный документ формируется построителем отчета. Как для всех выводимых числовых показателей установить вывод без дробной части?
Регистр «ПартииТоваровНаСкладах» имеет ресурсы
«Сумма» (точность: 2) и «Количество»(точность: 3). По регистру строится отчет посредством построителя отчета. Внешний вид табличного документа определяется настройками построителя отчета.
Необходимо обеспечить, чтобы все числовые показатели отчета выводились в формате целых чисел.
Для решения данной задачи лучше всего поработать с областями макета построителя отчета перед выводом построителя отчета в табличный документ.
Текст областей макета построителя отчета (названия параметров) будет определяться названиями выходных полей запроса.
Как правило, псевдонимы выходных полей запроса построителя отчета в своих именах упоминают имена ресурсов («Количество» или «Стоимость»). Обязательно проверьте - так ли это в Вашем случае. Для этого можно получить макет построителя отчета, как показано в примере «Где и как можно увидеть макет, автоматически генерируемый построителем отчета» на странице 262.
В результате можно утверждать, что в тексте областей макета построителя отчета, связанных с выводом информации по ресурсам, скорее всего, будут присутствовать упоминания названий этих ресурсов.
Значит, нам достаточно перебрать все области с текстом содержащим «Количество» или «Стоимость», и для каждой из них установить формат "ЧДЦ=0".
Находим в процедуре выведения построителя отчета на табличный документ сам момент выведения и перед ним дописываем:
// Получить макет построителя отчета.
Макет = ПостронтельОтчета.Макет;
// Сформатировать все области, где встречается слово «Стоимость» ТекущаяОбласть = Неопредслено;
Пока Истина Цикл
ТекущаяОбласть = Макет.НайтиТекстССтонмость”.
Текущая Область. Макет.ОбластьО);
Если ТекущаяОбласть = Неопределено Тогда Прервать;
Иначе
Если ТекушаяОбласть.Параметр о Тогда ТекущаяОбласть.Формат = "ЧДЦ=0";
КонецЕсли:
КонецЕсли;
КонецЦикла;
// Сформатировать все области, где встречается слово «Количество». ТскущаяОбласть = Неопределено;
Пока Истина Цикл
ТекущаяОбласть = Макет.НайтиТекстСКоличество”,
Текущая Область, Макет.Область());
Если ТекущаяОбласть = Неопределено Тогда Прервать;
Иначе
Если ТекущаяОбластъ.Параметр о Тогда ТскущаяОбласть.Формат = "ЧДЦ=0";
КонецЕсли;
КонецЕсли;
КонецЦикла;
// Назначить построителю измененный максг. ПостроительОтчета.Макет = Макет;
// Вывести результат работы построителя отчета в табличный документ
Сначала в переменную «Макет» получаем макет построителя отчета. Промежуточной переменной «ТекущаяОбласть» назначаем значение Неопределено.
Открываем цикл, который будет выполняться до точки прерывания. Внутри цикла находим очередную область табличного документа, в тексте которой упоминается слово «Стоимость». На первом витке цикла
это будет первая область от начала макета, на каждом очередном -следующая.
Если не удалось найти такую очередную область (то есть ее значение Неопрбделено) - прерываем цикл.
Если же удалось, проверяем, есть ли у данной области параметр. Если есть - меняем формат выводимых в этой области числовых данных. Форматная строка «ЧДЦ» определяет количество разрядов после запятой. В нашем случае - ноль. При этом сами данные будут при выводе округляться в соответствии с правилами округления, заданными для конфигурации.
Далее аналогичные действия выполняются для слова «Количество».
После всех циклов измененный макет отдаем в качестве значения макету построителя отчета.
Еще раз хочется подчеркнуть, что решение основано на известности названий выходных полей запроса построителя отчета. Необходимо искать области, текст которых содержит эти названия.
ф Как для построителя отчета совместить назначение своего макета и применение одного из стандартных макетов оформления?
ПоегроительОгчега.МакеЮформления =
ПолучитьМакетОформления(СтандартноеОформление. Апельсин): ПостроительОтчета.Макет = ПолучитьМакет(«МакегЭтогоОгчета»): Постронтель0гчета.ОформитьМакет();
Назначаем макет оформления построителя отчета, выбирая его из стандартных.
Устанавливаем макету построителя отчета значение макета, созданного вручную и хранимого в составе макетов этого отчета.
Для применения стандартного макета оформления к назначенному макету - перед выводом табличного документа необходимо использовать метод ОформитьМакет().
Замечание: «свой» макет должен иметь области со стандартными именами, иначе построитель не будет знать, что оформлять.
Как при получении данных из запроса обойти только итоговые записи?
При обходе результата запроса не хотим обходить детальные записи.
ТабДок = ЭлементыФормы.ПолеТабличногоДокумента:
ТабДок.Очистнть():
Макет = ПолучитьМакет(”Отчет”);
Запрос = Новый Запрос;
Запрос.Текст ~
"ВЫБРАТЬ
I ПродажиКомпанииОбороты.Номенклатура КАК Номенклатура,
I ПродажиКомпанннОбороты.Номенклатура.Представлеиие,
I ПродажиКомпанииОбороты.КолнчествоОборот КАК КоличествоОборот,
Как при получении данных из запроса обойти только иерархические итоговые записи?
I ПродажиКомпанинОбороты.СуммаПродажиОборот КАК СуммаПродажиОборот |ИЗ
I РегистрНакопления.ПродажиКомнании.Обороты(&НачПериода,&КонПсриода) КАК ПродажиКомпанииОбороты
|ИТОГИ СУММА(КоличсствоОборот), СУММА(СуммаПродажиОборот) ПО I ОБЩИЕ,
I Номенклатура Иерархия”:
Запрос.УстановнтьПараметрС'&НачПериода", НачПериода); Запрос.УстановитьПараметрС&КонПернода”, КонецДня(КонПериода)):
Результат = Запрос. Выпол ни гь();
ОбластьЗаголовок = Макет.ПолучнтьОбластьС'Заголовок");
ОбластьПодвал = Макет.ПолучитьОбластьС'Подвал”);
ОбластьШапкаТаблицы = Макет.ПолучитьОбластьС'ШапкаТаблицы”); ОбластьПодвалТаблицы = Макет.ПолучитьОбластьС'ПодвалТаблицы"); ОбластьОбщийИтог = Макет.ПолучитьОбласть("ОбщиеИтоги"); ОбластьНоменклатура = Макет.ПолучитьОбластьС'Номенклатура"); ОбластьДетальныхЗаписей = Макет.ПолучитьОбластьС'Детали");
Т абДок. В ы вести(ОбластьЗагол овок):
ТабДок.Вывести(ОбластьШапкаТаблнцы):
// Обход по определенным в запросе итоговым группировкам.
ВыборкаОбщийИтог = Результат
.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам):
// Запись общих итогов одна, поэтому нет необходимости в цикле. ВыборкаОбщийИтог.СледующинО;
ОбластьОбщнйИтог.Параметры.Заполнить(ВыборкаОбщийИтог):
ТабДок.Вывести(ОбластьОбщийИтог);
// Получить подчиненную выборку по итоговой группировке «номенклатура». ВыборкаНомснклатура = ВыборкаОбщийИтог
.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам):
Пока ВыборкаНоменклатура.СлсдующийО Цикл_
ОбластьНоменклатура. Параметры.Заполнит ь(ВыборкаНоменклатура): ТабДок.Вывести(ОбластьНоменклатура);
// Несмотря на то, что можем получить еще одну подчиненную // выборку (по детальным записям) мы это нс делаем, т.е. фактически // при обходе пропускаем детальные записи.
КонецЦнкла;
ТабДок.Вывести(ОбластьПодвалТаблицы);
ТабДок.Вывести(ОбластьПодвал):
Как при получении данных из запроса обойти только иерархические итоговые записи?
В примере «Как при получении данных из запроса обойти только итоговые записи» на странице 276 в методе Выбрать() вместо варианта обхода ПоГруппировкам необходимо использовать
ПоГруппировкамСИерархией.
В результате часть кода изменится:
ВыборкаОбщийИтог = Результат
. Выбрать(ОбходРезул ы атаЗапроса
.ПоГруппировкамСИерархией);
ВыборкаОбщийИтог.СледующийО;
Облает ьОбщийИтог.Параметры.Заполнить(ВыборкаОбщийІітог);
Т абДок. В ы вести(ОбластьОбщи й Итог);
ВыборкаНоменклатура = ВыборкаОбщийИтог
,Выбрать(ОбходРезультатаЗапроса
.ПоГруппировкамСИерархией);
Пока ВыборкаНоменклатура.СледующийО Цикл ОбластьНоменклатура. Параметры.Заполнить(ВыборкаНоченклатура): ТабДок.Вывести(ОбластьНоменклатура);
КонецЦнкла;
В результате в табличный документ будут выведены только:
• запись общих итогов (она относится к иерархическим)
• итоговые записи по группам справочника «Номенклатура» (иерархические итоговые записи)
Остальные данные (содержащиеся в результате запроса) обходиться не будут, таким образом, будут выданы только иерархические записи, расположенные на первом уровне.
ф Как вывести картинку в табличный документ?
В макете определим именованную область «ОбластьСКартинкой». В ней разместим элемент управления Картинка (имя «Логотип»), как показано на рисунке:

В процедуре, которая будет выполняться при формировании печатной формы, разместим следующий текст:
ТабДок = Новый ТабличныйДокумент:
Макет = ОбработкаОбъект.ПолучитьМакст("Макет");
ОбластьКартинки = Макет.ПолучитьОбласть( "ОблаегьСКартинкой"); Картинка = Новый Картинка(ПутьККартннке);
И Элемент управления "Логотип" входит в коллекцию картинок области. ОбластьКартинки. Рнсунки.Логотип. Картинка = Картинка:
ТабДок.Вывести!ОбластьКартинки);
ТабДок. ПоказатЦ);
Как вывести картинку в табличный документ без изменения макета?
Необходимо в шапке отчета (выводимого в поле табличного документа) отобразить логотип компании. При этом не нужно менять макет данного отчета.
Полный путь к картинке находится в одноименной переменной. Для решения задачи необходимо внести в процедуру, формирующую табличный документ следующие строки кода:
Область = Макет.ПолучнтьОбластьС’Шапка");
Рисунок = Область. Рисунки. ДобавіітМТнпРисункаТабличногоДокумснта. Картинка): Рисунок.Всрх = 5;
Рисунок.Высота = 10;
Рисунок.Ширина = 10;
РисунокЛево = 5;
Рисунок.Картинка = Новый Картинка! ПутьККартинке);
Рисунок.РазмерКартннкн = Размер Картинки. РеальныйРатмер;
ТабДок.Вывести(Область);
Первоначально создается новый элемент коллекции рисунков табличного документа. Далее устанавливается положение нового рисунка и, используя свойство Картинка, в новый рисунок загружается изображение из файла.
Как работать со сводной таблицей?
Для иллюстрации одного из способов работы со сводной таблицей создадим обработку. В диалоге основной формы разместим элемент управления ПолеТабличноГОДокумента (имя «ПолеДокумента»). В данном элементе управления необходимо выделить любую прямоугольную область и воспользоваться пунктом главного меню программы «Форма | Встроенные таблицы | Вставить сводную таблицу»:

При этом будет создана сводная таблица с именем « СводнаяТабл ица 1».
В процедуре обработчике нажатия на кнопку «Выполнить» разместим следующие строки:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
I ПродажиКомпанииОбороты.ДоговорВзаиморасчетовПокупателя.Владелец КА К ДоговорВзаи морас четов П окупателя Владелец,
I ПродажиКомпанииОбороты.Номенклатура КАК Номенклатура,
I ПродажиКомпанииОбороты.ПодразделениеКомпанни I КАК ПодразделениеКомпанин.
I СУММА(ГІродажиКомпанииОбороты.КоличествоОборот)
I КАК КоличествоОборот,
I СУММА(ПродажиКомпанииОбороты.СуммаПродажиОборот)
I КАК СуммаПродажиОборот
|ИЗ
I РегнстрНакопления. Продажи Компании.Обороты(&НачПериода,&КонПериода) КАК ПродажиКомпанииОбороты
ІСГРУППИРОВАТЬ ПО
I ПродажиКомпанииОбороты.ДоговорВзаиморасчетовПокупателя.Владелец.
I ПродажиКомпанииОбороты.Номенклатура,
I ПродажиКомпанииОбороты.ПодразделениеКомпанин
|ИТОГИ СУММА(КолнчествоОборот). СУММА(СуммаПродажиОборот) ПО I ДоговорВзаиморасчетовПокупателяВладелец,
I Номенклатура.
I ПодразделениеКомпанин";
// На состав полей, которые могут быть размешены в измерениях.
//данных сводной таблицы влияет раздел «Итоги».
Запрос.УстановитьПарамегрС'НачПериода". НачПернода): Запрос.УстановитьПараметрС'КонПериода". КонІ Іериода);
Результат — Запрос. Выполнитъ/);
Сводная = ЭлемснтыФормы Пол еДоку мента .ВстроенныеТаблицы .СводнаяТаблицаІ:
Сводная.ИсточникДанных = Результат;
В сводную таблицу передается результат запроса. Состав отображаемых полей определяется в диалоге, который вызывается путем выбора пункта «Отображать поля» контекстного меню сводной таблицы.
Как программно разместить данные в сводной таблице и оформить ее?
Для того чтобы облегчить чтение сводных таблиц, содержащих большое количество данных, можно использовать свойства сводной
таблицы МакетОформения и ОтображатьЛинии, позволяющее задать режим отображения линий, а для размещения данных использовать свойства сводной таблицы Строки, Колонки и Данные. Например:
Построитель = Новый ПостроительОтчета():
Построитель.Текст =
"ВЫБРАТЬ
I ТоварыНаСкладахОстаткиИОбороты.Склад КАК Склад.
I ТоварыНаСкладахОстаткиИОбороты.Склад.Представление,
I ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура, I ТоварыНаСкладахОстагкиИОбороты.Номенклатура. Представление.
I СУММА(ТоварыНаСкладахОстаткиИОбороты.КоличесгвоПриход)
I КАК КоличествоПриход,
I СУММАПоварыНаСкладахОсіаікнПОбороты.КоличесгвоОбороі)
I КАК КоличествоОборог.
I СУММА(ТоварыНаСкладахОстаткиИОбороты.КоличесгвоРасход)
КАК КолнчествоРасход
1113
I РегистрНаколлення.ТоварыНаСкладах.ОстаткиИОборогы КАК ТоварыНаСкладахОстаткиИОбороты
I
ІСГРУППИРОВАТЬ ПО 1 ТоварыНаСкладахОстаткиИОбороты.Склад,
I ТоварыНаСкладахОстаткиИОбороты.Номенклатура.
I ТоварыНаСкладахОстаткиИОбороты.Склад.Представлснис,
I ТоварыНаСкладахОстаткиИОбороты.Номенклатура.Представление
|ИТОГИ СУММА(КолнчествоПриход).
СУММА(КолнчествоОборот).
I СУММА(КоличествоРасход) ПО
I ОБЩИЕ,
1 Номенклатура ИЕРАРХИЯ,
1 Склад ИЕРАРХИЯ
Построй тсль.ЗаполнитьНастройкиС);
Таблица = ЭлементыФормы
.ПолеТабличногоДокумептаІ .ВстроенныеТаблицы .СводнаяТаблина I;
Таблица.МакетОформления =
ПолучитьМакетОформления(СтандарлноеОформление.Лед);
Таблица.ИсточникДанных = Построитель:
Таблица.Строки.ДобавитьС'Номснклатура"):
Таблица.Колонки .Добавить) "Склад”); Таблица.Данные.ДобавитьГКоличествоГІриход");
Гиб. іи па.О тиража і иІинни = ТнпОтображеніімЛіінийСво.іііоііТаб.іиііы
•Всегда;
Как создать печатную форму посредством текстового шаблона?
Требуется создать печатную форму для формирования заявок на пропуска сторонних лиц на встречи в офисе компании. Заявки впоследствии должны печататься на матричном принтере, поэтому для формирования выходной формы удобнее использовать текстовый документ:
Заявка на пропуска на 09.08.2004 Планируемое время посещения с 10:00:00
по 15:00:00
+
I
+
I
+
I
+
1
I
+
+------------------------------------------
I ФИО
+------------------------------------------
I Шлаков Семен Кузьмич
+------------------------------------------
I Кротов Иван Ильич
+------------------------------------------
I Колесниковская - Абдурахманова Александра I Константиновна
+------------------------------------------
Ответственный: _/Федоров
Для решения данной задачи создаем сначала макет текстового документа « ЗаявкаНаПропуск».

Макет сделаем следующего вида:
#Область Заголовок #Поле Дата
UФормат "ДФ= dd.ИИ.уууу"
UПоле ВремяНач
#Формат "ДЛФ=Т"
#Поле ВремяОконч
#Формат "ДЛФ-Т"
Заявка на пропуска на [Дата
Планируемое время посещения с [ВремяНач ]
по [ВремяОконч ]
I ФИО I
#КонецОбласти
^Область Состав
]I #Поля ФИО >I #Поля ФИО
I [
|<
+---------------
#Ко нецОб ласти
^Область Подвал
Ответственный: _/[Ответственный ]
#КонецОбласти
Каждая область заключается внутри маркеров ее начала и конца.
Форматирование выводимых в области данных можно производить посредством обращения к выводимому полю, далее «# Формат» и форматная строка. Аналогично там же можно производить выравнивание, например: «#Выравнивание Лево».
Вывод значений параметров определяется указанием имен параметров области между квадратными скобками. Количество разрядов между квадратными скобками определяет - во сколько разрядов будет помещено отображаемое текстом значение параметра.
Поэтому отдельный интерес представляет ситуация с выводом длинного, не вмещающегося в одной строке, текста. Она отработана при выводе строк области «Состав». Заметьте, в первой строке вывод поля указан в квадратных скобках, строкой ниже - в угловых. То есть вторая строка появится только тогда, когда выводимое не поместится в предыдущую строку.
Сам же текстовый документ будет формироваться так:
// Создать текстовый документ, в который будет выполняться вывод. ТекстДок = Новый ТекстовыйДокумент:
// Получить макет.
Макет - ПолучитьМакет("ЗаявкаНаПропуск"):
// Заголовок.
Область = Макет.ПолучитьОбластьГЗаіоловок"); Область.Параметры.Дата = Дата:
Область.ГІараметры.ВремяНач = НачалоСобытия: Область.Параметры.ВремяОконч = ОкончаннеСобытия;
Текст Док. Вывеет и(Область):
// Состав.
Область = Макет.ПолучитьОбластьС'Состав");
Для Каждого ТекСтрокаСторонннеЛица Из СторонниеЛнца Цикл Область.Парамстры.ФИО = Строка(ТекСтрокаСторотшеЛица.Лнцо): ТскстДок.Вывести(Облаегь);
КонецЦикла:
// Подвал.
Область = Макет.ПолучнтьОбластьГПодвал");
Область.Парамсгры. Ответственный = Ответственный. Наименование;
ТекстДок.Вывести(Область);
// Открыть сформированный документ.
ТекстДок.ПоказатьС'Заявка на пропуска для События №" + Номер);
Создаем в оперативной памяти текстовый документ. Для его заполнения используем текстовый макет, который мы создавали подчиненным документу «Событие».
Получаем область «Заголовок», производим заполнение ее параметров, выводим полученную область в текстовый документ.
В цикле перебора строк табличной части документа
«СторонниеЛица» производим заполнение и вывод области «Состав».
В подвале текстового документа выводим ответственного и показываем текстовый документ на экране.
Диаграммы
ф Как заполнить диаграмму данными?
Рассмотрим пример, позволяющий показать данные в круговой диаграмме. Данная диаграмма имеет одну точку и произвольное количество серий.
Первоначально в диалоге необходимо разместить элемент управления Диаграмма (имя элемента «Диаграмма»). В свойствах элемента управления укажем, что будем работать с круговой диаграммой.
Далее в модуле формы определить текст обработчика нажатия на кнопку «Выполнить»:
Диаграмма = Э.темснтыФормы.Диаірамма;
// Очистить диаграмму, возможно ранее в нее уже выводились данные. Диаграмма.КоличествоСернй = 0;
Диаграмма.КоличеетвоТочек = 0;
// Количество серий будет оіраннчивлться (не все значения будут показываться). Диаграмма. МаксимумСерий = МакснмумСерий.Ограничсно; Днаграмма.МаксимумСерийКолнчество = 7;
Диаграмма. ВидПодписей = ВидПодписейКДиаграмме.Процент: Диаграмма.ОблаетьЗаголовка.Текст = "Обороты номенклатуры";
Запрос = Новый Запрос:
Занрос.Текст = "ВЫБРАТЬ I ПродажиКомпанииОбороты. Номенклатура.
I СУММА»ПродажиКомпанииОбороты.КоличесгвоОборот)
КАК КоличествоОборот |ПЗ
I РегистрНакопления.Продажи.Обороты(,.,) КАК ПродажиКомпанииОбороты ІСГРУППМРОВАТЬ ПО
I ПродажиКомпанииОбороты.Номенклатура”;
Результат = Запрос. Выполнить!):
// Запретить обновление диаграммы на время вывода данных. Диаграмма.Обновление = Ложь;
// Установить единственную точку.
Диаграмма.КоличеетвоТочек = I;
Диаірамма.Точки[0]. Текст = "Количество";
Выборка = Результат.ВыбратьО;
Пока Выборка.Следующий!) Цикл
// Количество серий, если бы не ограничивали зависело бы от результата запроса КолнчествоСерий = Диаграмма.Серии.КоличествоО;
Диаі~рамма.КолнчествоСерий = КолнчествоСерий + 1; Диаграмма.Серни|КоличествоСернн].Текст= Выборка. Номенклатура:
// Установить значение «на пересечении» точки и серии.
// Первый параметр - 0 , так как в диаграмме только одна точка. Диаірамма.УстановитьЗначенне(0,
КолнчествоСерий,
Выборка. КоличсствоОборот);
КонецЦикла;
// Обновить диаграмму.
Диаграмма.Обновление = Истина;
В результате выполнения этого кода будет сформирована следующая диаграмма:
Следует заметить, что специфика круговой диаграммы заключается в том, что она содержит одну точку и некоторое количество серий. В других видах диаграмм для вывода аналогичных данных номенклатуру лучше назначать точкам диаграммы. Кроме этого, заполнение диаграммы данными может быть выполнено также через свойство ИСТОЧИ И кДанных аналогично тому, как заполняется сводная диаграмма в примере «Как заполнить данными измерительную диаграмму?» на странице 289.
Как заполнить данными измерительную диаграмму?
Чаще всего при выводе в измерительную диаграмму, необходимо настроить полосы диаграммы, и, возможно, максимальное и минимальное значения шкалы диаграммы. Следующий пример демонстрирует настройку и вывод данных в измерительную диаграмму при помощи кода, однако надо заметить, что аналогичную на стройку измерительной диаграммы можно выполнить интерактивно в палитре свойств:
// Настроить свойства диаграммы.
Диаграмма = ЭлементыФормы.ДиаграммаПродажи; Диаграмма.ТипДиаграммы = ТипДиаграммы. Измерительная: Диаграмма.АвтоМаксимальносЗначение = Ложь;
Диаграмма.МаксимальноеЗначение = 20000;
Диаграмма. АвгоМинимальноеЗначение = Ложь;
Диаграмма.МинимальноеЗначение = 0;
// Создать три полосы.
Полосы = Диаграмма.ПолосыИзмерительнойДиаграммы;
НоваяПолоса = Полосы ДобавитьО;
Новая Полоса. Начало = 0;
НоваяПолоса.Конец = 1000;
НоваяПолоса.ЦветФона =\?сЬЦвеіа. Красный;
НоваяПолоса = Полосы.Добавить();
НоваяПолоса.Начало = 1000;
НоваяПолоса.Конец = 5000:
НоваяПолоса.ЦветФона =\?еЬЦвета.Желтый:
НоваяПолоса = Полосы.Добавить();
НоваяПолоса.Начало = 5000;
НоваяПолоса.Конец = 20000:
НоваяПолоса.ЦветФона = Web Цвета. Зел е н ы й;
Запрос = Новый Запросе
ІВЫБРАТЬ |
|
1 ПродажиОбороты.Период.
1 ПродажмОбороты.СтоимостьОборот |
|
|
|ИЗ |
|
|
1 РегнстрНакоішения.Г1родажи.Обороты(&ДатаНача;іа. &ДатаОкончания, День,) |
КАК ПродажиОбороты
1"); |
|
|
Запрос.УстановитьПараметрС'ДатаНачала". '2004.08.10 00 |
00:00’); |
|
Запрос.Установить! ІараметрС'ДатаОкончания". '2004.08.30 23:59:59'); |
|
ЭлсмснтыФормы.ДнаграммаПродажи.ИсточникДанных = |
Запрос
.ВыполнитьО
ВыірутитЫ); |
В результате работы данного кода будут получены данные о продажах за четыре дня августа 2004 года (в другие дни продаж не было), которые отобразятся в измерительной диаграмме четырьмя стрелками, указывающими на объем продаж:
* Отчет Отчет!
Действия » і ?J
20000
і ром I и
15 08 20IJ4
О 00 Гіи 18.08 2004 0 00 00 20 08 2004
о ии но
2208.2004
0:00:00
Просмотреть Сформировать Закрыть
Для того чтобы отобразить результат запроса в сводной диаграмме, следует использовать свойство сводной диаграммы ИСТОЧНИКДЗННЫХ, а затем установить нужные значения серий, точек и ресурсов диаграммы:
Запрос = Новый Запрос)
"ВЫБРАТЬ
I ТоварыНаСкладахОстаткиИОбороты.Склад КАК Склад.
I ТоварыНаСкладахОстаткнИОбороты.Склад. Представление.
I ТоварыНаСкладахОстаткиИОбороты.Номенклатура КАК Номенклатура. I ТоварыНаСкладахОстаткиИОбороты.Номенклатура.Представление.
I СУММА(ТоварыНаСкладахОстаткиИОбороты.КоличествоПриход)
КАК КоличествоПрнход,
I СУММА(ТоварыНаСкладахОстаткиИОборогы.КоличсствоОборот)
КАК КоличествоОборот,
I СУММАіТоварыНаСкладахОстагкиНОбороты. КоличествоРасход)
КАК КоличествоРасход |ИЗ
I РсгнстрНакопления.ТоварыНаСкладах.ОстаткнИОбороты КАК ТоварыНаСкладахОстаткиИОбороты
ІСГРУППИРОВАТЬ ПО I Товары Н аС кладах Остатки И Обороты .Склад.
I ТоварыНаСкладахОстаткиИОбороты.Номенклатура,
I ТоварыНаСкладахОстаткиИОбороты.Склад.Прсдставление,
I ТоварыНаСкладахОстаткиИОбороты.Номенклатура.Представлсние
|ИТОГИ СУММА) КоличествоПрнход),
СУ М М А) Кол н чествоОборот),
СУММА)КоличествоРасход) ПО I ОБЩИЕ,
I Номенклатура ИЕРАРХИЯ.
) Склад ИЕРАРХИЯ');
Диаграмма = ЭлементыФормы.СводнаяДиафаммаІ;
Диаграмма.ОбластьЗаголовка.Текст = "Приход товаров";
Диаірам.ча.ИсточникДанных = Запрос.Выполнить)); Диаірамча.Серии.ДобавнтьС'Номенклатура");
Диаграмма.Точки. Добавить) "Склад");
Диаграмма. Ресурсы .Добавить)" КоличествоПриход”):
В данном примере сводная диаграмма «СводнаяДиаграммаІ», расположенная в форме отчета, заполняется данными, полученными в результате выполнения запроса:

Программное добавление серий, точек и ресурсов диаграммы выполнять не обязательно - можно предоставить пользователю возможность самостоятельно разместить в сводной диаграмме данные, используя системный интерактивный диалог:

Данный диалог можно вызвать, используя пункт контекстного меню элемента управления сводная диаграмма.
Как заполнить диаграмму Ганта данными?
Создадим обработку. В диалоге основной формы разместим элемент управления Диаграмма Га ШЭ (имя элемента управления «ДГ»). В обработчик события нажатия на кнопку «Выполнить» поместим следующие строки:
ДГ = ЭлсментыФормы.ДГ;
// Установить заголовок диаграммы.
ДІ .ОбластьЗаголовка.Текст = "График дежурств”;
// Интервал будем определять самостоятельно. ДГ.АвтоОпределсниеПолногоИнтервала = Ложь;
// Установить интервал.
ДГ.УстановнтьПолныйИнтервал(НачалоМесяиа(ТекущаяДата()),
КонецМесяца(ТекущаяДатаО));
// В диаграмме будет две точки - сотрудники Петров и Сидоров...
ТочкаП = ДГ.УстановитьТочкуСТІстров");
ТочкаС = ДГ'.УстановитьТочкуС'Сидоров");
// и две серии - дежурство на вахте и дежурство в центральном офисе. СерияНаВахте = ДГ.УстановнтьСернюС'На вахте1');
СерияВЦентре = ДГ.УстановитьСериюСВ центральном офисе");
// Задать цвета серий, отличные от цвета по умолчанию.
СерияНаВахте.Цвет = ??сЬЦвета.Синий;
СерияВЦентре.Цвет = \?еЬЦвета.СветлоЖелтый;
ПервыйДень = НачалоМесяца(ТекущаяДатаО);
// Получить значение диаграммы - дежурство Петрова на вахте.
Значение = ДГ.Г1олучитьЗначение(ТочкаІІ. СерияНаВахте);
// В значении определить новый интервал.
Интервал = Значение.ДобавитьО;
Интервал.Текст = "Работает на вахте”;
//Определить границы интервала.
Интервал.Начало = ПервыйДень;
Интервал.Конец = ПервыйДень + 10*24*60*60;
// Получить значение диаграммы - дежурство Петрова в центральном офисе. Значение = ДГ.ПолучитьЗначение(ТочкаП. СерияВЦентре);
Интерват = Значение.ДобавитьО;
Интервал.Текст = "Работает в центральном офисе";
Интервал.Начало = ПервыйДснь + 14*24*60*60;
Интервал. Конец = ГІервыйДень + 24*24*60*60;
// Получить значение диаграммы - дежурство Сидорова на вахте.
Значение = ДГ.ПолучитьЗначение* ГочкаС, Серия НаВахте);
Интервал = Значение.ДобавитьО;
Интервал.Текст = "Работает на вахте";
Интервал.Начало = ПервыйДснь + 5*24*60*60;
Интервал.Конец = ПервыйДснь + 15*24*60*60;
// Получить значение диаграммы - дежурство Сидорова в центральном офисе. Значение = ДГ.ПолучитьЗначеннеіТочкаС. Серия ВЦентре);
Интерват = Значение.ДобавитьО;
Интерваі.Текст = "Работает в центральном офисе";
Интервал. Начато = ПервыйДень + 21*24*60*60;
Интервал. Конец = ПервыйДснь + 25*24*60*60;
Для того чтобы заполнить диаграмму Ганта, необходимо создать нужные серии (в нашем случае это виды дежурств), точки (в нашем случае это сотрудники) и заполнить свойства значений диаграммы для каждой пары точка - серия. Значение диаграммы представляет собой в общем случае совокупность нескольких интервалов. В данном примере каждое значение диаграммы содержит лишь один интервал, для которого задается начало, конец и текст, выводимый в качестве подсказки при наведении курсора мыши на этот интервал.
В результате работы этого кода будет сформирована следующая диаграмма:

В реальных механизмах данные для построения, скорее всего, будут получаться из базы данных, в соответствии с этим будет меняться и алгоритм работы с диаграммой.
Как связать интервалы диаграммы Г анта?
Диаграмма Ганта позволяет устанавливать связи между различными интервалами диаграммы. Для иллюстрации этой возможности доработаем пример «Как заполнить диаграмму Ганта данными?» на странице 293.
Чтобы связать между собой интервалы дежурств каждого из сотрудников, добавим в этот пример следующий код:
// Получить значение диаграммы - дежурство Петрова на вахте.
Значение = ДГ.ПолучитьЗначеннеРГочкаП. СерняНаВахте);
// В значении определить новый интервал.
Интервал = Значение.Добавить)):
//Запомнить интервал начала связи.
СвязьИнтервалНачало = Интервал;
И Получить значение диаграммы - дежурство Петрова в центральном офисе. Значение = ДГ.ПолучитьЗначсниеСГочкаП. СерияВЦентре):
Интервал = Значение.ДобавитьО;
// Запомнить интервал окончания связи.
СвязьИнтервалКонец = Интервал;
// Связать два интервала.
Связь = СвязьИнтервалНачало.Добивить(СвязьИнтсрва.ік'онец); Связь.Цвет = \?еЬЦвета.Синин;
// Получить значение диаграммы - дежурство Сидорова на вахте.
Значение = ДГ.ПолучитьЗначение(ТочкаС, Серия НаВахте);
Интервал = Значение.ДобавитьО;
СвязьИнтервалНачало = Интервал;
// Получить значение диаграммы - дежурство Сидорова в центральном офисе Значение = ДГ.ПолучзпьЗначение(ТочкаС, СерияВЦентре);
Интервал = Значение.ДобавитьО;
СвязьИнтервалКонец = Интервал;
// Связать два интервала.
Связь = СвнзьИнгервалНачало.Добавить(СвязьИнтервал Конец); Связь.Цвет = З?еЬЦвета.Синий;
Для добавления связи необходимо выполнить метод Добавить() того интервала диаграммы, который является началом связи. В качестве параметра этого метода необходимо передать интервал диаграммы,
который будет являться окончанием этой связи. Кроме этого можно задать другие свойства связи, например цвет.
В результате будет получена следующая диаграмма:

Как обработать интерактивное изменение интервалов диаграммы Ганта?
Для того чтобы пользователь имел возможность интерактивного изменения интервалов диаграммы Ганта, необходимо свойству Редактирование нужных интервалов присвоить значение Истина:
|
// Получить значение диаграммы - дежурство Петрова на вахте. |
|
Значение = ДГ.ПолучитьЗначениеіТочкаГІ. СсрияМаВахте): |
|
|
// Разрешить интерактивное редактирование иіпервалоі Значеиие.Редактированне = Истина; |
. |
// Получить значение диаграммы - дежурство Петрова в цен Значение = ДГ.ПолучитьЗначеннс(ТочкаП. СерняВЦентре);
Значснис.Редактнрование = Истина; |
¦ральном офисе. |
|
// Получить значение диаграммы - дежурство Сидорова на вахте. |
Значение = ДГ.ПолучитьЗначение(ТочкаС. СерияНаВахте);
Значение.Редактирование = Истина; |
|
|
// Получить значение диаграммы - дежурство Сидорова в центральном офисе. |
|
Значение = ДГ.ПолучитьЗначенисіТочкаС. СерняВЦентре); Значение.Редактирование = Истина; |
|
Интерактивное изменение интервалов диаграммы Ганта приводит к
генерации события При окончании редактирования интервала.
Используя обработчик этого события, можно выполнять различные
действия, связанные с изменением интервалов. Например, можно «дискретизировать» перемещение границ интервалов, «округлив» их до нужного значения или изменить цвет связи между интервалами, если интервалы «перекрывают» друг друга:
Процедура ДГПриОкончанииРедактированияИнтервала(Элемент,
Интервал.
Отмена)
//Сгладить погрешности интерактивного перетаскивания -// округлить интервал по границе дня.
Интервал.Начало = Интервал.Начало + 3600 * 12;
Интервал.Начало = НачалоДня(Интервал.Начало);
Интервал.Конец = Интервал.Конец + 3600 * 12;
Интервал.Конец = НачатоДня(Интервал.Конец);
// Скорректировать цвета связей.
Дтя Каждого Связь Из Интервал Цикл
Если Связь.Начало.Конец <= Связь.Конец.Начало Тогда Связь.Цвет = ??еЬЦвета.Синий;
Иначе // есть пересечение интервалов - выделить красным Связь.Цвет = ??еЬЦвета. Красный.
КонецЕсли;
КонецЦикла:
КонецПроцедуры_
Если добавить этот код к примеру «Как связать интервалы диаграммы Ганта?» на странице 295, то изменение границ интервалов диаграммы станет возможным с «точностью до дня», а при частичном перекрытии связанных интервалов связь между ними будет отображаться кэасным цветом.

Как разместить непериодические метки в диаграмме Ганта?
Диаграмма Ганта позволяет размещать на шкале времени непериодические метки, которые могут использоваться для обозначения контрольных точек или произвольных событий, связанных с отображаемыми в диаграмме данными. В качестве развития примера «Как обработать интерактивное изменение интервалов диаграммы Ганта?» на странице 296, можно добавить в диаграмму две непериодические метки, которые будут обозначать события проверки дежурств, выполняемых сотрудниками:
// Установить непериодические метки - контроль дежурства.
// Создать отдельный элемент шкалы времени (для более наі лядного отображения) ЭлементМеток = ДГ.ОбластьПостроення.ШкалаВречени.Элементы. Добавит ь(); ЭлементМеток.Единица = ТипЕдиницыШкалыВремсни.День;
// Скрыть периодические метки добавленного элемента. ЭлементМсток.ОтображатьПериодичсскиеМетки = Ложь:
// Установить метку - первая проверка - 10 часов утра 9 числа.
ПерваяПроверка = ПервмйДснь + 8 * 24 * 60 * 60 + 10 * 60 * 60;
Метка = ЭлементМеток.Метки.Добавить(ПерваяІІроверка);
Метка.Текст = "Проверка";
Метка. ЦветТекста = З?еЬЦвета. Красный:
Метка.ЦветЛинии = Метка.ЦветТекста;
И Установить метку - вторая проверка - 8 часов вечера 23 числа.
Вторая Проверка = ПервыйДень + 22 * 24 * 60 * 60 + 20 * 60 * 60;
Метка = ЭлементМеток Метки.Добавить(ВтораяПроверка);
Метка.Текст = "Проверка";
Метка.ЦветТекста = З?еЬЦвета. Красный:
Метка.ЦветЛинии = Метка.ЦветТекста;
Для добавления непериодических меток мы используем дополнительный элемент шкалы времени лишь для более наглядного отображения меток. Те же самые метки можно было бы добавить и в существующий элемент шкалы времени. Также для каждой метки мы задаем текст, цвет надписи и цвет линии, которая будет отображать эту метку в диаграмме.
В результате будет получена следующая диаграмма:

Как выделить некоторые интервалы фона диаграммы Ганта?
Диаграмма Ганта позволяет выделять цветом фона произвольные интервалы. Эта возможность может использоваться, например, для «подсветки» выходных дней.
Для иллюстрации этой возможности к примеру «Как разместить непериодические метки в диаграмме Ганта?» на странице 298, можно добавить код, который выделит выходные дни другим цветом фона диаграммы:
// Выделить выходные дни другим цветом фона. Неделя = 3600 * 24 * 7:
Выходные = 3600 * 48;
МаксимальнаяДата = ПсрвыйДень + Неделя * 4; ТекущаяДата = Первый День;
Пока ТекущаиДага <- МаксимальнаяДата Цикл; Конец = НачалоНелели(ТекущаяДата):
Начало = Конец - Выходные; ДГ.ИнтервалыФона.Добавить(Начало, Конец);
ТекущаяДата = ТекущаяДата + Неделя; КонецЦикла;
Чтобы выходные дни выделить другим цветом, мы добавляем нужные интервалы к коллекции интервалов фона диаграммы. Цвет создаваемых интервалов мы не меняем - используем назначаемый по умолчанию.
В результате будет получена следующая диаграмма:

Географическая схема
Ф Как отобразить в форме файл географической схемы?
Для этого следует разместить в форме поле географической схемы (например, «ГеоСхема») и выполнить метод Пр0ЧИТЗТЬ():
Схема = ЭлементыФормы ГеоСхема;
Схема. npo4HTaTb("D:/MyGeo.geo”);
® Как отобразить в форме макет географической схемы?
Для этого следует расположить в форме поле географической схемы (например, «ГеоСхема»), а затем получить макет географической схемы (в следующем примере это один из общих макетов), и вывести его в поле в форме:
Схема = ЭлементыФормы.Г еоСхема;
Схема. Вывссти(ПолучитьОбщийМакет("ГеографичсскаяСхемаРоссин"));
(D Как изменить масштаб географической схемы?
Для этого следует установить соответствующий режим отображения географической схемы (ЗадаетсяМасштабом) и задать требуемый масштаб:
Масштаб = 100000;
Если ВвестиЗначение(Масштаб) Тогда ЭлементыФормы.ГеоСхема.ПолдержкаМасштаба =
РежимОтображенияГеографическойСхемы. ЗадаетсяМасштабом ЭлементыФормы.ГеоСхема.Масштаб = Масштаб;
КонецЕсли:
Как отобразить на географической схеме выбранный город?
Предположим, что в форме расположено поле географической схемы («ГеоСхема»), в которую выведен макет регионов России, содержащий слои «Регионы» и «Города» (такой макет, например, содержится в демонстрационной конфигурации «Географическая схема» ИТС). Требуется предоставить пользователю возможность выбрать из списка некоторый город и затем отобразить этот город на карте России. Эта задача может быть выполнена при помощи следующего кода:
Схема = ЭлементыФормы. ГеоСхема;
СпнсокГородов = Новый СписокЗначений; |
|
|
// Запретить перерисовку схемы на время обновления. Схема.Обновленне = Ложь; |
|
// Отобразить слой Регионы.
Схема.Слои.Регионы.Видимость = Истина; |
|
// Задать тип отображения названий городов.
СлойГорода = Схема.Слои.Города; СлойГорода.Ссрии.Название.ТипОтображения = |
|
|
ТипОтображенияСерииСлояГ'еоі |
рафическойСхемы.Текст; |
// Сформировать список городов и скрыть все города.
Для Счетчик = 0 По СлойГорода.Объекты.Количество() - 1 |
Цикл |
Г ород = СлойГ орода.Объекты.Получить(Счетчик); Город.Видимость = Ложь;
НазваниеГорода = Слой Города. ПолучитьЗначение( Город |
|
|
СлойГорода.Серии. Название); |
|
НазваниеРегиона = СлойГорода |
|
|
,ПолучитьЗначение(Город, СлойГорода.Серии.Регион); |
|
С иисокГо родов. Добавить! С четчнк. |
|
|
НазваниеГорода.Значение + " |
|
|
+ НазваниеРегиона.Значение 4 |
|
|
КонецЦикла; |
|
|
СлойГорода.Видимость = Истина; // Отобразить слой Города. |
|
СписокГородов.СортироватьІІоПредставлсннюО; ВыбранныйГород = СписокГородов.ВыбратьЭлементО; Если ВыбранныйГород о Неопределеио Тогда |
|
|
ГородСхемы = СлойГорода.Обьекты.Получить(Выбранн |
ыйГород.Значение); |
|
ГородСхемы.Видимость = Истина; // отобразить выбранный город |
КонецЕсли;
Схема.Обновление = Истина; // Обновить схему. |
|
Географическая схема
В этом примере осуществляется обход всех объектов слоя «Города», и формируется список городов, который затем открывается для выбора пользователю. После того, как пользователь выбрал город, видимость выбранного объекта устанавливается в значение Истина. Поскольку для серии «Название» задан тип отображения Текст, рядом с городом будет отображено и его название.
Как использовать таблицу значений в качестве источника данных географической схемы?
Для иллюстрации работы географической схемы с произвольным источником данных расположим в форме поле географической схемы (например «ГеоСхема») и под ним табличное поле («ИсточникДанныхГеоСхемы»), связанное с таблицей значений.
В поле географической схемы выведем макет регионов России, содержащий слои «Регионы» и «Города» (такой макет, например, содержится в демонстрационной конфигурации «Географическая схема» ИТС). Затем выполним следующий код, который создаст источник данных типа На Пересечен И И и назначит его географической схеме:
Схема = ЭлементыФормы.ГеоСхема;
Схема.Обновление = Ложь: // Запретить обновление схемы.
// Отобразить слои Регионы и Города.
Схема.Слои.Регионы.Виднмость = Истина;
СлойГорода = Схсма.Слои.Города:
СлойГорода.Вндимость = Истина;
// Добавить новую серию для отображения данных источника.
СсрияИнформацня = Схема.Слои.Города.Серии.ДобавитьС'Информапия"); СерияИнформация.Значение = "Информация";
// Сформировать таблицу значений источника данных.
ИсточникДанныхГеоСхемы.Колонки .ДобавитьС'ЗначениеГоро да"); ИсточникДанныхГеоСхемы. Колонки.ДобавнтьС'СерияИнформацня",
Новый ОписаниеТиповС’Строка"));
//Добавить "справочную" колонку в истоник данных // (нужна только для "наглядности" работы с источником). ИсточникДанныхГеоСхемы.Колонки.Добавить("НазваниеГоро да”);
// Заполнить в первой строке источника данных значение серии.
// для которой будут выводиться данные.
ИсточникДанныхГеоСхемы.ДобавитьО.СерияИнформация = "Информация":
// Задать тип источника данных
Схема.Слои.Города.ТнпОрганизацииИсточникаДанных =
ТипОрганизацииИсточникаДанныхГеографическойСхемы.НаІІересечении;
// Задать тип отображения значений серии источника данных. СлойГорода.Серии.Информация.ТинОтображения =
ТипОтображенияСерииСлояГеоі рафическойСхемы.Текст;
// Заполнить источник данных значениями всех объектов.
Для Каждого Город Из СлойГорода.Объекты Цикл Город.Видимость = Истина;
СтрокаИсточникаДанных = ИсточникДанныхГеоСхемы.Добавить(); СтрокаИсточникаДанных.ЗначениеГорода = Город.Значение: СтрокаИсточникаДанных.НазванисГорода = СлойГорода
ПолучитьЗначенис(Город, СлойГорода.Серии.Название) .Значение;
КонецЦикла;
Элемен гыФормы.МсточникДанныхГеоСхемы.Создать Колонки));
Схема.Обновленне = Истина; // Обновить поле географической схемы.
// Назначить источник данных.
СлойГорода.ИсточннкДанных = ИсточникДанныхГеоСхемы;_
Табличное поле «ИсточникДанныхГеоСхемы» иллюстрирует устройство источника данных типа На Пересечен И и. В первой колонке расположены значения объектов, а во второй - должны находиться те значения, которые должны быть отображены для этих объектов в серии «Информация». Серия, в которой должны отображаться значения, идентифицируется своим значением, которое указывается в первой строке источника данных в соответствующем столбце (в нашем случае это строка «Информация»). Последняя колонка в источник данных добавлена исключительно в «демонстрационных» целях. Этой колонке не соответствует никакая серия в слое Города, поэтому она просто игнорируется географической схемой.
Введя произвольные значения в колонку таблицы «СерияИнформация», можно увидеть, что они будут отображены для соответствующих объектов слоя «Города».
Следует учитывать, что данный пример лишь иллюстрирует работу с источником данных, поэтому он содержит для наглядности все объекты слоя Города (около 2 500 городов), что замедляет его работу. Кроме того, в реальных задачах обычно в качестве источника данных используется не таблица значений, а результат запроса, имеющий аналогичную структуру.
Администрирование
Запуск 1С:Предприятия из командной строки
ф Как запустить 1 С:Предприятие из командной строки?
Для запуска 1С:Предприятия в пользовательском режиме, в случае если база данных функционирует в файловом варианте.
“C:\Program Files\lcv8\bin\lcv8.exe" ENTERPRISE /F ОЛКонфи і'урации?Г шювые\У прТорг /N ИмяПользователя /Р Пароль
Для запуска 1С:Предприятие в режиме «Конфигуратор», в случае если база данных функционирует в файловом варианте.
"C:\Program Files\lcv8\bin\lcv8.exe" CONFIG IF 0:\Конфигурации\Типовые\УпрТорг /N ИмяПользователя /Р Пароль_
Для запуска 1 С: Предприятие в пользовательском режиме, в случае если система функционирует в клиент-серверном варианте.
"C:\Program Files\lcv8\bin\lcv8.exe" ENTERPRISE /S Сервер?База
IN ИмяПользователя /Р Пароль
Для запуска 1С:Предприятие в режиме «Конфигуратор», в случае если система функционирует в клиент-серверном варианте.
"C:\Program Files\lcv8\bin\lcv8.exe" CONFIG IF 0:\Конфигурации\Тнповые\УпрТорг /N ИмяПользователя /Р Пароль
ENTERPRISE - режим «Предприятие»
CONFIG - режим «Конфигуратор»
/F Путь к базе, функционирующей в файловом режиме /S ИмяСервера\ИмяБазы, функционирующей в клиент-серверном режиме
/N Имя пользователя /Р Пароль пользователя
Замечание: в этих и последующих примерах командная строка отформатирована (добавлен перенос на следующую строку) для повышения наглядности. В реальных примерах весь текст должен записываться в одну строку.
Как из командной строки заставить 1С:Предприятие сделать выгрузку базы данных?
В командной строке необходимо прописать следующее:
"C:\Prograin Files\lcv8\bin\lcv8.exe" CONFIG /F 0:\Конфигурации\Типовые\УпрТорг /N ИмяПользователя /Р Пароль /DumpIB сЛммя.сІІ
Как из командной строки обновить изменения текущей конфигурации в конфигурации базы данных?
|
В командной строке необходимо прописать следующее: |
|
|
|
|
"C:\Prograin Files\lcv8\bin\lcv8.exe" CONFIG /F [):\Конфш урации\Типовые\УпрТорг /N ИмяПользователя /Р Пароль /UpdateDBCfg |
|
|
Запуск 1С:Предприятия из командной строки
Как выполнить тестирование и исправление информационной базы без проверки ссылочной целостности в автоматическом режиме?
Для этого следует использовать режим пакетного запуска конфигуратора из командной строки:
"C:\Program Files\lcv8\bin\lcv8.exe" CONFIG /F"C:\Documents and Settings\user\My Documents\lC\DemoTrd2” Л?'Федоров (администратор)” /Р”"
/IBcheckAndRepair -Loglnlegrity
Параметр /IBcheckAndRepair позволяет выполнить тестирование и исправление информационной базы, а ключ -Loglntegrity указывает, что при проверке логической целостности не будет выполняться проверка ссылочной целостности.
Каквыполнить проверку конфигурации в автоматическом режиме с выводом результатов проверки в файл?
Для этого следует использовать режим пакетного запуска конфигуратора из командной строки:
"C:\Program Files\lcv8\bin\lcv8.exe" CONFIG /F'C:\Documents and Settings\user\My Documems\IC\DemoTrd2”
/№Федоров (администратор)" /Р""
/OutD.\my\Jog.txt
/CheckConfig -ClientServer -Client -ExtemalConnectionServer -ExtemalConnection
-Server -DistributiveModules -IncorrectReferences -ConfigLogicallntegrity -UnreferenceProcedures -HandlcrsExistence -EmptyHandlers
Параметр /Out позволяет задать имя файла, в который будут выводиться результаты проверки. Параметр /CheckConfig позволяет выполнить проверку конфигурации, при этом используются следующие ключи:
-ClientServer - Работа клиентского приложения в режиме клиент -сервер. Проверка компиляции модулей в режиме эмуляции среды клиентского приложения, выполняемого в режиме клиент - сервер.
-Client - Работа клиентского приложения. Проверка компиляции модулей в режиме эмуляции среды клиентского приложения, выполняемого в файловом режиме.
-ExternalConnectionServer - Работа внешнего соединения. Проверка компиляции модулей в режиме эмуляции среды внешнего соединения, выполняемого в режиме клиент - сервер..
-Server - Работа сервера 1 С:Предприятия. Проверка компиляции модулей в режиме эмуляции среды сервера 1 С: Предприятия.
-DistributiveModules - Поставка модулей без исходных текстов. В случае если в настройках поставки конфигурации для некоторых модулей указана поставка без исходных текстов, проверяется возможность генерации образов этих модулей.
-IncorrectReferences - Поиск некорректных ссылок. Поиск ссылок на удаленные объекты. Выполняется по всей конфигурации, включая права, формы, макеты, интерфейсы и т.д. Также осуществляется поиск логически неправильных ссылок.
-Config Logical Integrity - Проверка логической целостности конфигурации. Стандартная проверка, обычно выполняемая перед обновлением базы данных.
-UnreferenceProcedures - Поиск неиспользуемых процедур и функций. Поиск локальных (не экспортных) процедур и функций, на которые отсутствуют ссылки. В том числе осуществляется поиск неиспользуемых обработчиков событий.
-HandlersExistence - Проверка существования назначенных обработчиков. Проверка существования обработчиков событий интерфейсов, форм и элементов управления.
-EmptyHandlers - Поиск пустых обработчиков. Поиск назначенных обработчиков событий, в которых не выполняется никаких действий. Существование таких обработчиков может привести к падению производительности системы.
Запуск 1С предприятия из командной строки
Как сократить журнал регистрации программно?
Для этого следует использовать режим пакетного запуска конфигуратора из командной строки с параметром
/ReduceEventLogSize:
"C:\Program Files\lcv8\bin\lcv8.exe" CONFIG /F"C:\Documents and Settings\user\My Documents\lC\DemoTrd2" /Ы"Фелоров (администратор)" IP""
/OutD:\my\log.txt
/ReduceEventLogSize 2004-12-26 -saveAsC:\OldLog.elf_
После параметра /ReduceEventLogSize обязательно должна быть указана новая граница журнала регистрации, а ключ -saveAs позволяет указать файл, в который будут сохранены копии выгружаемых записей.
Как выгрузить модули прикладного решения в виде текстовых файлов из командной строки?
Для этого можно использовать режим пакетного запуска конфигуратора из командной строки с параметром /DumpConfigFileS:
"C:\Program Files\lcv8\bin\Icv8.exe" CONFIG /F"C:\Documents and Settings\user\My Documenls\lC\DemoTrd2' ^"Федоров (администратор)" IP""
/DumpConfigFiles "D:\1\I 1” -Module
После параметра /DumpConfigFiles указывается каталог, в котором будут находиться выгруженные файлы, а ключ -Module указывает, что необходимо выгружать только модули, содержащиеся в конфигурации.
Как загрузить в прикладное решение файлы справки, сохраненные в формате htm?
Для этого можно использовать режим пакетного запуска конфигуратора из командной строки с параметром /LoadConfigFiles:
"C:\Program Files\lcv8\bin\lcv8.exe" CONFIG /F"C:\Documents and Settings\user\My Documents\lC\DcmoTrd2' /N''Федоров (администратор)" /Р"“
/LoadConfigFiles "D:\l\ll" -Help_
После параметра /LoadConfigFiles указывается каталог, в котором находятся загружаемые файлы, а ключ -Help указывает, что загружать нужно только файлы справки.
Разное
ф Как поменять значение рабочей даты?
Прежде чем устанавливать значение рабочей даты на «УстанавливаемаяДата», необходимо убедится, что рабочая дата не определяется системной датой компьютера:
Если ИспользованнеРабочейДаты = РежимРабочейДагы.Назначать Тогда РабочаяДата = УстанавливаемаяДата;
Иначе
СообщитьС'Рабочая дата не будет сменена.
[Необходимо сначала в меню Сервис-Парамстры-Обшая |снять флажок - Использовать текущую дату компьютера ")
КонецЕсли;
Проверка осуществляется для свойства глобального контекста ИспользованиеРабочейДаты на равенство значению Назначать системного перечисления Режим РабочейДаты. В случае выполнения условия назначаем значение свойству глобального контекста РабочаяДата.
Какустановить/снять монопольный режим?
Установленный монопольный режим позволит пользователю быть единственным пользователем базы, пока он установлен. Однако сам монопольный режим возможно установить только в том случае, если на момент установки пользователь был единственным:
Попытка
УстановитьМонопольныйРежнм(Истина);
Исключение
ПредупрсждениеС'К базе подключены пользователи.
[Монопольный режим установить невозможно!", 7).
КонецПопыткн:
Как видите, если применение процедуры работы с информационной базой УстановитьМонопольныйРежим() приводит к ошибке приходится с этим смириться. Хотя если захотите обеспечить выход других пользователей из системы - в настоящем издании есть пример
того, этого добиться: «Как принудительно завершить работу всех пользователей информационной базы в клиент-серверном варианте работы?» на странице 320.
Кроме самой установки монопольного режима можно еще, например, убедиться, что в текущий момент работа идет в монопольном режиме:
Если МонопольныііРежимО Тогда СообщитьС’Монополыіын режим установлен"); КонецЕсли;
Или же снять монопольный режим:
УсгановнтьМонопольныйРсжнм(Ложь);
(D Как внести запись в журнал регистрации?
Основные события системы (запись, удаление объектов и т.п.) при установках соответствующей политики ведения журнала регистрации заносятся туда автоматически. Однако есть еще возможность регистрации дополнительных действий.
Например, приведенный ниже код позволит регистрировать факты обращения пользователя к отчету «Рапорт руководителя». Его надо лишь разместить в соответствующем обработчике события.
ЗаписьЖурналаРегисграцин("ОтчетныеДанные. Просмотр",
УровеньЖурналаРеі истрацин. Информация Метаданные)),
ДатаКон,);
В качестве параметров можно указывать:
• событие (строковое описание, допустимо использование «.»);
• уровень важности события (будет отображено соответствующей пиктограммой). Тип значения - элемент системного перечисления УровеньЖурналаРегистрации;
• объект метаданных. В нашем случае определили его посредством соответствующего метода;
• данные. Для указания ссылок на объекты, с которыми связано данное событие. Например, на конкретный документ или элемент справочника. В нашем случае - указали переменную содержащую дату формирования отчета;
• комментарий.
ф Как получить данные о зарегистрированных пользователях информационной базы?
Данная задача может возникать при выгрузке подобных данных в другую информационную базу, или при первичном заполнении справочника «Пользователи».
Выборка = ПользователиИнформационнойБазы.ПолучитьПользователеШ):
Для Кажлого Элемен (Массива Из Выборка Цикл ИмяПользователя = ЭлементМассива.Имя;
ПолноеИмяПользователя = ЭлементМасснва.ПолноеИмя;
ЕстьПароль = ЭлсмснтМассива.ПарольУстановлеи:
Роли = ЭлсментМассива.Роли:
Для Кажлого Роль Из Роли Цикл ИмяРоли = Роль.Имя;
КонецЦикла;
КонецЦикла;
В указанной процедуре работа по получению списка пользователей начинается с обращения к свойству глобального контекста
ПользователиИнформационнойБазы. Метод
ПолучитьПользователейО возвращает массив объектов
ПользовательИнформационнойБазы, который обходится потом в цикле.
(D Как определить общую системную информацию?
Получить подобное предупреждение:

можно посредством такого кода:
Инфо = Новый Системная! Інформация;
Текст = "Версия ІС:Предприятия 8.0: " + Инфо.ВерсияПриложения;
Текст = Текст + Символы.11C + "Конфигурация: ” + Метаданные.Синоним;
Текст = Текст + Символы.ПС + "Поставщик: " + Метаданные.Поставщик;
Текст = Текст + Символы.ПС + "Операционная система: " + Инфо.ВерсияОС:
Текст = Текст + Символы.ПС +
"Оперативная память (МБ): " + Инфо.ОиеративнаяПамять;
Текст = Текст + Символы.ПС + "Процессор:" + Инфо.Процессор;
Предунреждение(Текст,,
"ДАННЫЕ ТЕКУЩЕГО КОМПЬЮТЕРА И КОНФИГУРАЦИИ"):
Создаем конструктором новый объект СистемнаяИнформация. Считываем из него версию приложения, версию операционной системы, данные об оперативной памяти и процессоре. Данные о конфигурации считываем из глобального контекста, объект Метаданные.
Как программно добавить пользователя в информационную базу?
При переносе данных из одной информационной базы в другую может возникнуть необходимость перенести и пользователей информационной базы. Для этого можно воспользоваться свойством глобального контекста ПользователиИнформационнойБазы:
Новый Пользователь = ПользователпИнформационнойБазы.СоздагьПользователяО НовыйПользователь.Имя = "Имя”; .
НовыйПользователь.ПолноеИмя = "Фамилия Имя Отчество"; НовыйПользователь.АутентифнкацияСтандартная = Истина; НовыйГІользователь.ОсновнойИнтерфейс = Метаданные
.Интерфейсы
.Администратор;
НовыйПользователь.Пароль = "пароль";
НовыйПользоватсль.Роли.Добавить(Метаданные.Роли. Администратор); НовыйПользователь.ПоказыватьВСпискеВыбора = Ложь; НовыйПользовагель.Язык = Метаданные.Языки.Русский; НовыйПользователь.Записа і ь();
Следует отметить, что в свойство Пароль можно только записать новый пароль, прочитать записанный (определенный) ранее нет возможности.
Замечание: добавление новых пользователей в информационную базу может осуществлять пользователь, обладающий административными правами. Если административные права у пользователя отсутствуют - он может изменить только ограниченный набор сведений о себе.
Для того чтобы предоставить, например, менеджеру, не имеющему административных прав, возможность добавления новых пользователей с правами менеджера, можно поступить следующим образом.
Создать обработку, с помощью которой менеджер будет задавать имя, пароль, набор ролей и другие свойства нового пользователя. Однако запись нового пользователя выполнять не на клиенте, а на сервере, передав нового пользователя в качестве параметра в процедуру привилегированного модуля:

В этом случае система не будет выполнять проверку прав пользователя, поэтому о проверке необходимых прав нужно позаботиться самостоятельно. Например, процедура привилегированного модуля может выглядеть следующим образом:
|
Процедура ЗалисатьНовогоПольэователя(НовыйПользова |
ель) Экспорт |
|
// Проверить наличие роли Администратор у нового пол |
•зоватсля. |
|
РольАдминистратор = Метаданные.Роли.Администрато| Если НовыйІ1ользователь.Роли.Содержит(РольАдмннис |
к
гратор) Тогда |
|
СообщитьС'Добавление пользователя с адмииистратив |
іыми правами |
|
Ізапрешено."); |
|
|
Иначе // у нового пользователя нет роли Администратор |
|
// Проверить, что текущий пользователь обладает прав И или Администратора
Если РольДоступнаІ РольАдминистратор) ИЛИ |
імн Менеджера |
|
РольДоступна(Мегаданныс.Ролн.Менсджер) Тоі |
іа |
// Выполнить запись новою пользователя.
Новый П ол ьзовател ь.Зан исать(); |
|
Иначе
СообщитьС'Недостаточно прав доступа для добавлеі КонсцЕсли; |
ия пользователя."); |
|
КонецЕсли: |
|
|
КонецПроцсдуры |
|
Если выполняется попытка добавить нового пользователя с административными правами - выдается запрет. Если набор ролей нового пользователя не содержит роль «Администратор» проверяется, является ли текущий пользователь менеджером или администратором -и если это так, то выполняется запись нового пользователя. В противном случае выдается сообщение об отсутствии прав доступа.
Как создать собственный лог-файл для записи результатов работы внешней обработки?
Для этого можно использовать объект ЗаписьФаЙЛЗ, который позволяет выводить текстовые строки в указанный файл:
ФайлРепістрации = Новый 3aiiHCbTeKCTa("C:\LogFile.txt".
КоднровкаТексіа.АЫ.ЧІ,
Истина);
ФайлРепістрации.Запнсать( "Первое сообщение" + Символы.IІФ); ФайлРегистрации.ЗаписатьС'Второе сообіцение”+ Символы.ПФ);
Файл Регистрации .ЗакрытьО:
При создании нового объекта ЗаписьТекста в качестве четвертого параметра конструктора указывается значение Истина, что говорит о том, что содержимое файла будет сохранено, если файл уже существует.
Как в форме отобразить список пользователей, которые работают с данной информационной базой?
Для этого можно расположить в форме табличное поле (например, с именем «Пользователи»), и воспользоваться методом глобального контекста ПолучитъСоединенияИнформационнойБазы(), который возвращает массив, состоящий из описаний соединений с текущей информационной базой:
МассивСоединений = ПолучнтьСоединенняИнформационнойБазы!);
Колонки = Пользователи.Колонки;
Колонки.ДобавитьСПользователь".,, 10);
Колонки.Добавить!"Приложение",,, 10);
Колонки.ДобавитьС'НачалоРаботы",,, 10);
Колонки.Добавить! "Компьютер",,. 10);
Колонкн.ДобавитьС'Сосдиненнс",., 10);
Для Каждого Соединение из МассивСоединений цикл НоваяСтрока = Полыователи.Добави іь();
НоваяСтрока.Комньютер = Соединение.ИмяКомпыогера; НоваяСтрока.Прнложение = Предс і авленнеі I риложенп я! Соединение
НмяПриложення);
НоваяСтрока.НачалоРаботы = Соединение.НачалоСеанса; НоваяСтрока.Соединение = Соединение.НомерСоединения;
НоваяСтрока.Пользователь = Соединение.Пользователь.Имя;
КоиецЦикла;
Э.тементыФормы.Пользователи.СоздатьКотонкиО;
Как выгрузить журнал регистрации в XML-формате?
Для анализа событий, происходивших при работе прикладного решения (например, с использованием консоли анализа журнала регистрации) может потребоваться выгрузка журнала регистрации в формате XML.
Выгрузка всего журнала может быть выполнена следующим образом:
Выі рузитьЖу риал Регистрации! "C:\log.xml");
Если требуется, например, выгрузить только события, связанные с определенными пользователем (пользователями), можно в форме расположить список (например «СписокПользователей»), заполнить его имеющимися пользователями:
Пользователи = I Іольюватели Информационной базы. Получить! ІользователейО;
Для Каждого Пользователь из Пользователи цикл НовыйЭлемент = СпнсокПользователей.ДобавитьО;
НовыйЭлемент.Пометка = Истина;
НовыйЭлемент.Значенне = Пользователь;
НовыйЭлемент.Представление = Пользователь.Имя;
КонецЦикла;
А затем, отметив нужных пользователей, выгрузить только те записи журнала регистрации, которые относятся к выбранным пользователям:
Массив = Новый Массив;
Дтя Каждого Пользователь из СписокПользователей Цикл
Если Пользователь.Пометка Тогда Массив. Добавить(Пользователь);
КонецЕсли;
КонецЦикла;
СтруктураФильтра = Новый Структура; СтруктураФильтра.ВставитьС'Пользователь". Массив); ВыгрузитьЖурналРегистращш("С:\1о§.хтГ.
СтруктураФильтра,
"Дата, Пользователь, ПредставлениеСобытия");
Как принудительно завершить работу всех пользователей информационной базы в клиент-серверном варианте работы?
Для этого можно воспользоваться возможностью программного доступа к серверу 1С:Предприятия. Нужно создать СОМ-коннектор и выполнить метод ConnectServer(), который позволяет подключиться к указанному серверу 1С:Предприятия.
Затем следует аутентифицироваться с правами администратора в выбранной информационной базе, получить все клиентские соединения этой базы и разорвать их:
Коннектор = Новый СОМОбъект("?8.СОМСоппесЮг");
Сервер = KoHHeKTop.ConneclServerC'TeslServer");
И Аутентифицироваться с административными правами в нужной базе. Сервер. АіІііАиІйеМісаііопС'Администратор","");
// Создать объект нужной информационной базы.
ИнформационнаяБаза = CepBep.CreatelnfoBaselnfoO:
Информационная База.Name = TestBasc”;
// Получить соединения базы.
Соединения Базы = Сервер.Се(ІВСошіесІіопя(ИнформационнаяБаза);
// Разорвать соединения клиентских приложений.
Для Каждого Соединение Из СоединенияБазы Цикл Сервер, ПіясоппесКСосдинение);
КонецЦикла:
Интеграция
Текстовый файл
® Как выгрузить данные из справочника в текстовый файл?
Текст = Новый ТскстовыйДокумснт;
Выборка = Справочники.Номенклатура.ВыбратьО;
Пока Выборка.СледующийО Цикл Стр = СтрЗаменить(Выборка. Наименование, Символ(34), "%квч%"): Код = Строка(Выборка.Код) + Символ(34); Текст.ДобавигьСтроку(Код + Стр);
КонецЦикла;
TeKCT.3amicaTb("c:\lemp\texI.txt");
В строке текста значения реквизитов справочника разделяются символом кавычка. Его можно получить, например, используя функцию Символ(34). В случае если символ разделителя (в данном случае -кавычка) может встречаться в выгружаемых данных, то перед помещением в строку меняем этот символ на заранее определенную комбинацию символов. В нашем случае это «%квч%». Считается, что подобная комбинация символов не может встретиться в данных.
(D Как загрузить данные из текстового файла?
Текст = Новый ТекстовыйДокумент;
Текст. Прочитать!''e:\temp\text.txl");
Для НомерСтрокн = I По Текст.КоличествоСтрокО Цикл Стр = Текст.ПолучитьСтроку(НомерСтроки);
Позиция = Найти(Стр, Символ(34));
Код = Сред(Стр. 1, Позиция-1); прНаименование = Сред(Стр. Позиция + I):
Наименование = СтрЗаменитьІпрНаименование, "%квч%", Символ(34));
Сообшить(Код + + Наименование);
КонецЦикла;
При загрузке ориентируемся на используемый разделитель значений (это кавычка). После получения значения делаем обратное преобразование для разделителя (при выгрузке данных кавычку, встречающуюся в выгружаемых строках, заменяли на комбинацию символов «%квч%»)
Работа с текстом. Модель последовательного доступа
Если в предыдущем примере текстовый документ загружался полностью, то в следующих примерах документ загружается «построчно». Это позволяет при работе с файлами больших размеров значительно уменьшить время выполнения задачи.
Запись данных в файл:
Путь = "c:\temp\text.txt";
Текст = Новый ЗаписьТекста(Пугь, КодировкаТекста.ІЛТв): Выборка = Справочники.Номенклатура.Выбрать!);
Пока Выборка.СледующийО Цикл Текст.ЗаписатьС троку( Выборка. Наименование); КонецЦикла;
Текст.За крыть!);
Текстовый файл
Чтение данных:
Путь = "c:\temp\text.txt";
Текст = Новый ЧтениеТекста(Путь, КоднровкаТекста.1)ТН8): Стр = Текст. ПрочитатьСтрокуО;
Пока Стр о Неопределено Цикл Стр = Текст.ПрочитатьСтрокуО;
Сообшнть(Стр);
КонецЦикла;
XML
ф Как из одной базы перенести документ в другую базу?
Необходимо экземпляр документа «РеализацияТоваровУслуг» (ссылка на который выбирается в диалоге создаваемой обработки) перенести в другую базу данных. Структура конфигураций идентична. Справочники (и другие сопутствующие объекты) синхронизированы по значениям внутренних идентификаторов.
Для выгрузки потребуется выполнить следующий фрагмент кода:
// Выгрузить в файл xml.
ЗаписьХМЬ=Новый ЗаиисьХМЦ); ЗаписьХМЬ.(>ткрытьФай.'[( "c:\doc. xml"); ЗаписьХМІ..ЗаписатьНачалоЭлемента("ІіооГ);
// Получить объект по ссылке. ВыгружаемынОбъект=Документ.ПолучитьОбъектО:
// С помощью средств сериализации записать объект в файл ЗаписатьХМЦЗапнсьХМЬ.ВыгружасмыйОбъект):
ЗаписьХМи.ЗаписатьКонец'ЗлемснтаО;
ЗаписьХМЬ.ЗакрытьО;
При выгрузке создаем элемент «Root» исходя из соображений, что в xml-документе должен быть только один корневой узел, а в общем случае (но не в нашем) выгружаться может не один объект.
Для загрузки выгруженного значения используем следующий фрагмент кода:
ЧтениеХМЕ=Новый ЧгениеХМЦ);
ЧтениеХ ML.Открыт ьФаГі.і("с:?1ос.хтІ")'.
//Текущим становится элемент Root.
Чтсн исХ М L. П рочитать!);
// Текущим становится элемент с документом. ЧтеннеХМЬ. Прочитать!):
// Проверить сможет ли с данным значением "справиться' // система сериализации в данной базе.
Если Возможное!ьЧтенияХМЕ(ЧтениеХМЕ) Тогда
// Получить ДокументОбъект.РеализацияТоваровУслуг
ЗагружаемыйОбъект=ПрочитатьХМЬ(ЧтениеХМЬ);
ЗагружаемыйОбъект.ЗаписатьО;
КонецЕсли:
ЧтеннеХМЕ. Закрыть!):
Как можно сформировать XML-документ произвольной структуры?
Путь к формируемому XML-документу указан в переменной «ПутьКФайлу». Используется модель последовательного доступа (работа осуществляется только с одним текущим узлом).
Запись = Новый ЗаписьХМЬ;
Запись.ОткрытьФайл(ПутьКФайлу);
Запись.ЗаписатьОбъявлениеХМЦ);
Запись.ЗаписатьНачалоЭлементаС’Корневой");
Запись.ЗаписатьАтрибут("Справочник“, "Номенклатура"): Запись.ЗаписатьКомментарийС'Краткая информация о номенклатуре"): Выборка = Справочники.Номенклатура.ВыбратьИерархическиО:
Пока Выборка.СледующийО Цикл
Если Выборка.ЭтоГруппа Тогда Продолжить;
КонецЕсли;
Запись. ЗаннсатьНачалоЭлемента( "Элемент"); Запись.ЗанисатьЛтрибутС'Код", Строка(Выборка.Код)); Запись.ЗаписатьАтрибут("Артикул", Строка(Выборка.Арт икул)); Запись.ЗаписатьТекст(Выборка.Наименование); Запись.ЗаписатьКонецЭлементаО:
КонецЦикла;
Запись.ЗаписатьКонецЭлементаО:
Запись.ЗакрытьО:
В результате будет получен файл вида (просмотр в Internet Explorer):
<Корневой Справочник="Номвнклатурам>
с:Элемент Код=”6” Артикул=”1234”>В|д (капилярная)Э.г <Элемент Код=”3” Артикул---” 1235”>Паркер "Golg"3J18M«
<Элемент Код=”5” Артикул=”1 236”>Шариковая обычная <Элемент Код=”7” Артикул=п1237”>КоИ!пог мЭлемент>
< Э л е м е н т К о д=” 8” А р т и к у л=!! 12 3 8” > Ко h i n о г т Эл емент >
< Э л е м ент К од=” 4й А р т и к у л=і! 12 3 9” > Ко h i n о г т м Э л е м е н т >
<Элемент Код=”14” Артикул=”1240”>Агс!о TL 1000 ЕХ-1
<Элемент Код=”15” Артикул=*1241я>1т1в5Н: WS 105 ТХ
<Элемент Код=”11!! Артикул=Н1242Н>ВО8СН KGS 3760 1Е<
< Элемент К од=”12” ApTSiK’nn=”1243”>ELECTROLUX ER 900 Корневой>
Можно сказать, что XML-документ состоит из набора элементов. Элемент можно упрощенно представить в виде совокупности структурных единиц:
< НачалоЭлемента
ИмяАтрибута=Значение ИмяАтрибута=Значение......>
Текст
< КонецЭлемента>
Создание XML-документа с помощью объекта 3anMCbXML производится путем помещения в строгой последовательности (иначе будет нарушена структура) «частей» узлов.
Как сформировать XML-документ в строку?
Требуется, чтобы запись XML-документа производилась не в файл, а в строку. Рассмотрим пример:
Запись = Новый ЗаписьХМЦ);
Запись.УстановитьСтрокуО:
Занись.ЗаписатьОбъявлениеХМЬО;
Запись.ЗаписатьНачалоЭлемента( "Корневой"): Запись.ЗалнсатьАтрибутС'Справочник", "Номенклатура"); Запись.ЗаписатьКомментарийГ'Краткая информация о номенклатуре") Выборка = Справочники. Номенклатура. ВыбратьИерархичсскиО;
Пока Выборка.СледуюшийО Цикл
Если Выборка.'ЗгоГруппа Тогда Продолжить;
КонецЕсли;
Запись.ЗаписатьНачалоЭлементаСЭлсмент");
Запись.ЗаписатьАтрибут("Код", Строка(Выборка.Код)); Занись.ЗапнсатьАтрибутС’Артикул", Строка( Выборка. Артикул)); Запись.ЗаннсатьТекст( Выборка. Наименование);
Запись. ЗаписатьКонецЭлементаО;
КонецЦикла:
Запись.ЗаписагьКонсцЭлементаО;
Стр = Запись.Закрыть;);
Сообщить(Стр);_
Для вывода X ML-доку мента в строку после создания объекта ЗаписьХМЦ необходимо использовать метод УстановитьСтроку(). Только в этом случае метод Закрыть() вернет строку, которая будет содержать сформированный X ML-документ.
Как можно обмениваться данными, используя XML-сериализацию через файлы других форматов?
Под XML-сериализацией понимается возможность записи или чтения данных из 1С:Предприятие 8.0 в (из) XML-документ. Но фактически при выгрузке данных выгружаемое значение агрегатного типа можно посредством сериал изации преобразовывать в фрагмент XML и сохранять в файлах произвольных форматов как строковое.
Необходимо выгрузить экземпляр документа, ссылка на который находится в переменной «СсылкаНаДокумент» в текстовый файл:
3anncbXML = Новый ЗаписьХМЦ); ЗаписьХМЦУстановитьСтрокуО:
Данные = СсылкаНаДокумент.ПолучитьОбъектО: ЗаписатьХМИ ЗаписьХМЦ Данные): ТекстСообщсния = ЗаписьХМЦЗакрытьО;
Текст = Новый ТекстовынДокумент;
Текст.УстановитьТекст(ТекстСообщения):
Тскст.Записать(ПутьКФайлу);
Метод УстановитьСтрокуО устанавливает режим вывода данных не в XML-файл, а в строку (строка возвращается при выполнении метода
Закрыть()).
В другой базе необходимо загрузить данные из полученного текстового файла:
Текст = Новый ТекстовынДокумент; Текст.ІІрочитать(ПутьКФайлу);
Ч гениеХМІ. = Новый ЧтениеХМЦ);
ЧтениеХМ ЦУстановитьСтроку (Текст. ПолучитьТекстО);
Если ВозможностьЧтенняХМЦЧтениеХМЬ) Тогда Данные = ГІрочитатьХМЦЧтеннеХМІЛ;
Данные.Записать)):
КонецЕсли;
Следует отметить, что данный механизм будет работать в том случае если документ в базе данных источника и приемника имеет абсолютно одинаковую структуру.
Как можно загрузить XML документ произвольной структуры?
Как можно построить выгрузку-загрузку посредством файлов DBF?
Путь к загружаемому X ML-доку менту указан в переменной «ПутьКФайлу». Используется модель последовательного доступа. В данном примере под загрузкой будет пониматься чтение данных и вывод их в окно служебных сообщений. Загружать будем документ, выгруженный в предыдущем примере.
Чтение = Новый ЧтениеХМЬ;
Чтение.ОткрытьФайл(ПутьКФайлу):
Пока Чтение.ПрочитатьО Цикл // Прочитать «структурные части» элементов
// Проверить, какая часть элемента — текущая.
Если Чтение.ТипУзла = ТипУзлаХМЬ.НачалоЭлемента Тогда 11 мяУтла = Чтение.Имя,
СообщитьС—" + ИмяУзла);
// Атрибуты элементов можно читать только если текущая часть -И начало элемента
Пока Чтение.ПрочитатьАтрибутО Цикл
// Прочитать данные узла атрибута.
ТипУзла = Чтение.ТипУзта;
Имя = Чтение.Имя;
Значение = Чтение.Значение;
// Обработать полученные значения.
КонецЦикла;
ИначеЕслн Чтеннс.ТипУзла = ТипУзлаХМЬ.Текст Тогда
// В примере просто выводим текст в окно сообщений. СообщитьС’Текст:" + Чтение.Значение);
ИначеЕсли Чтение.ТипУзла = ТипУзлаХМЬ.КонецЭлемента Тогда
// В примере просто выводим признак конца элемента
И в окно сообщений
СообщитьС—Конец:" + Чтение.Имя);
КонецЕсли;
КонецЦикла
Объект ЧтениеХМ1_ производит чтение данных, используя модель последовательного доступа. В этой модели обход документа производится именно по его структурным элементам последовательно, за исключением узлов атрибутов, для которых необходимо организовывать вложенный цикл.
Приведем фрагмент данных выводимых в окно служебных сообщений:

DBF-файлы
® Как можно построить выгрузку-загрузку посредством файлов DBF?
Не смотря на то, что формат DBF считается уже устаревшим, может возникнуть необходимость работы с файлами данного формата.
Выгрузка данных:
БД = Новый XBase:
БД.Поля.Добавить("СООЕ", "S", 5);
БД.Поля.Добавить)"NAME", "S", 40);
БД.СотдатьФайлЦІуть + "start.dbf", Путь + "index.cdx");
БД.Индексы.Добавить)"IDXCODE", "CODE");
ФлИБД = БД.СоздатьИндексныйФаГіл(Пугь + "index.cdx"); БД.АвтоСохранение = Истина:
Выборка = Справочники. Номенклатура. ВыбратьИсрархическиО;
Пока Выборка.СледующийО Цикл БД.ДобавитьО;
БД.ССЮЕ = Выборка.Код;
БД^АМЕ = Выборка! Іаимснованис:
КонецЦикла;
БД.ЗакрытьФайл));_
Загрузка данных:
БД = Новый XBase;
БД.ОткрыгьфайліПуть + "start.dbf". Путь + "index.cdx”); БД.ТекущийИндекс = БД.Индексы.ЮХССЮЕ;
Пока БД.СледующаяО Цикл Сообщить) БД.СОПЕ);
Сообщить) БД.ЫАМЕ);
КонецЦикла;
БД.ЗакрытьФайлО;_
Работа с HTML-документами
Ф Заполнение HTML-анкет
Необходимо заполнить анкету, реализованную как HTML-документ и расположенную на веб-сервере. Будем считать, что необходимо внести данные о фамилии, имени, отчестве физического лица.
Фрагмент HTML-кода анкеты выглядит следующим образом: