Циклы - это та часть программного текста, которая пишется от руки, каркас цикла можно взять из встроенных шаблонов.
Текст запросов в 1С строится автоматически с помощью конструктора запросов или Конструктора запросов с обработкой результата (здесь в конце текста запроса будет добавлен цикл Пока для вывода всех строк пока они есть в таблицу значений и затем таблица значений будет выведена в табличное поле на форму).
1. пример цикла по коллекции Структура (поиск значения по ключу-строке).
/// Как обойти все элементы Структуры в 1с 8.3, 8.2
Для Каждого Элемент Из ЛичныеДанные Цикл Сообщить(Элемент.Ключ + " " + Элемент.Значение);
КонецЦикла;
// на месте ЛичныеДанные может быть регистр сведений.
2. пример цикла по коллекции Соответствие (поиск значения по ключу любого типа)
// Как обойти все элементы Соответствия в 1с 8.3, 8.2
Для Каждого Элемент Из СобытияДаты Цикл Сообщить(Строка(Элемент.Ключ) + " " + Элемент.Значение); КонецЦикла;
// переменная в цикле СобытияДаты - это коллекция Соответствие.
3. пример цикла по коллекции Массив (у нас в примере массив чисел).
// в массиве сразу 3 элемента
Числа = Новый Массив(3);
// инициализируем их значениями
Числа[0] = 5;
Числа[1] = Числа[0] * 2; // 10
Числа[2] = Числа[1] * 2; // 20
// выводим на печать
Для Каждого ЭлементМассива из Числа Цикл Сообщить(ЭлементМассива); // напечатает числа 5 10 20
КонецЦикла;
4. пример цикла по коллекции Список значений (поиск значения по его представлению)
/// Как обойти элементы списка значений в 1с 8.3, 8.2
Для Каждого Элемент Из Список Цикл
Сообщить (Элемент.Представление + ": " + Строка(Элемент.Значение) ); КонецЦикла;
5. пример цикла по коллекции Таблица значений (поиск значения(любого типа) по номеру строки или индексу)
Чаще всего таблица значений используется в программировании на платформе 1С как данные, хранящиеся в памяти во время выполнения программы. Далее пример , в котором показано использование таблицы значений для временного хранения результатов запроса для последующего вывода данных таблицы значений на форму.
/// Как программно вывести на форму результат запроса /// в виде таблицы значений в 1с 8.3, 8.2
&НаСервере
Процедура ВывестиНаФормуРезультатЗапросаНаСервере()
Запрос = Новый Запрос; Запрос.Текст =
"ВЫБРАТЬ
| Товары.Ссылка,
| Товары.ВерсияДанных,
| Товары.ПометкаУдаления,
| Товары.Код,
| Товары.Наименование,
| Товары.Цвет,
| Товары.ЕдиницаИзмерений,
| Товары.Предопределенный,
| Товары.ИмяПредопределенныхДанных
|ИЗ
| Справочник.Товары КАК Товары";
РезультатЗапроса = Запрос.Выполнить();
ТабВКоде = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.Прямой);
// функция ВывестиТаблицуЗначенияВКодеВТаблицуНаФорме определена выше ВывестиТаблицуЗначенияВКодеВТаблицуНаФорме(ТабВКоде, "ТабРеквизит2", "ТабНаФорме2");
КонецПроцедуры
Далее пример использования таблицы значений в цикле.
/// Как программно вывести таблицу значений на /// форму в 1с 8.3, 8.2
// ТабВКоде - таблица значений, созданная программно
// ТабРеквизит - имя реквизита формы типа ТаблицаЗначений
// ТабНаФорме - имя элемента формы, связанного с ТабРеквизит
&НаСервере
Процедура ВывестиТаблицуЗначенияВКодеВТаблицуНаФорме(ТабВКоде, ТабРеквизит, ТабНаФорме)
// реквизит ТабРеквизит и соответствующий
// ему элемент формы ТабНаФорме уже созданы
// нами в визуальном режиме
// 1. добавляем колонки из ТабВкоде в реквизит ТабРеквизит.
НовыеРеквизиты = Новый Массив;
Для Каждого Колонка Из ТабВКоде.Колонки Цикл НовыеРеквизиты.Добавить( Новый РеквизитФормы( Колонка.Имя, Колонка.ТипЗначения, ТабРеквизит ) );
КонецЦикла;
ИзменитьРеквизиты(НовыеРеквизиты);
// 2. добавляем колонки из ТабВКоде в элемент ТабНаФорме.
Для Каждого Колонка Из ТабВКоде.Колонки Цикл
НовыйЭлемент = Элементы.Добавить( ТабРеквизит + "_" + Колонка.Имя, Тип("ПолеФормы"), Элементы[ТабНаФорме] ); НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода; НовыйЭлемент.ПутьКДанным = ТабРеквизит + "." + Колонка.Имя; КонецЦикла;
// 3. наконец, передаём данные из ТабВКоде в ТабРеквизит
ЗначениеВРеквизитФормы(ТабВКоде, ТабРеквизит);
КонецПроцедуры
6. Дерево значений.
Дерево значений представляет собой динамически формируемый набор значений любого типа, сходный с объектом ТаблицаЗначений. В отличие от таблицы значений, строки дерева значений могут образовывать иерархические структуры: каждая строка дерева может иметь набор (коллекцию) подчиненных строк, каждая из подчиненных строк в свою очередь также может иметь набор подчиненных строк и так далее. При этом поиск значений, сортировка, получение итогов могут осуществляться либо по текущему уровню иерархии, либо включая все подчиненные. Дерево значений может иметь визуальное представление, если с ним связать элемент управления ТабличноеПоле. Внешний вид такого элемента будет похож на дерево групп справочника.
Необходимо отметить, что дерево значений, связанное с элементом управления ТабличноеПоле, будет иметь все колонки, имеющиеся в табличном поле, с соответствующими именами.
Кроме того, дерево значений может иметь также и собственные колонки, не отображаемые в табличном поле, при этом их имена должны отличаться от имен колонок табличного поля.
Процедура ПолучитьДеревоНаСервере()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Родитель КАК Родитель,
| Номенклатура.Ссылка КАК Номенклатура
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ИТОГИ ПО
| Родитель";
ПромДерево = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ЗначениеВРеквизитФормы(ПромДерево, "ДеревоЗн");
КонецПроцедуры
Здесь стоит особенно обратить внимание на два фактора, без которых дерево не сформируется:
- строка в запросе «ИТОГИ ПО Родитель»
- и Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией.
Обход дерева значений с помощью рекурсии
В основном обход дерева в 1С делается с помощью рекурсии. Даже когда известно, сколько уровней в нем. С рекурсией это проще, всего около шести строк:
&НаКлиенте
Процедура ОбходДерева(Команда)
ОбойтиДеревоНаСервере();
КонецПроцедуры
&НаСервере
Процедура ОбойтиДеревоНаСервере()
ДеревоЗнач = РеквизитФормыВЗначение("ДеревоЗн");
ОбходДереваДетально(ДеревоЗнач);
КонецПроцедуры
//Рекурсивная процедура (выполняется быстрее)
&НаСервере
Процедура ОбходДереваДетально(ПереданноеДер)
Для Каждого СтрПолученногоДерева Из ПереданноеДер.Строки Цикл
Сообщить(СтрПолученногоДерева.Номенклатура);
Если СтрПолученногоДерева.Строки.Количество()>0 Тогда
ОбходДереваДетально(СтрПолученногоДерева);
КонецЕсли;
КонецЦикла;
КонецПроцедуры