Найти в Дзене

Я_программист_1С. Циклы в программировании на коллекциях значений представленных на платформе 1С.

1. пример цикла по коллекции Структура (поиск значения по ключу-строке).
/// Как обойти все элементы Структуры в 1с 8.3, 8.2
Для Каждого Элемент Из ЛичныеДанные Цикл Сообщить(Элемент.Ключ + " " + Элемент.Значение);
КонецЦикла;

Циклы - это та часть программного текста, которая пишется от руки, каркас цикла можно взять из встроенных шаблонов.

Текст запросов в 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 Тогда
ОбходДереваДетально(СтрПолученногоДерева);
КонецЕсли;
КонецЦикла;
КонецПроцедуры