Первый шаг в 1С — абсолютно бесплатно.

📋 Универсальная коллекция - Массив в 1С 8.3

Определение массива и примеры

Массив в 1С 8.3 — это универсальная пронумерованная коллекция значений произвольного типа, где элементы располагаются друг за другом и доступны по индексу (начиная с 0).

В одном массиве можно хранить значения разные по типу: ссылки на документы, числа, строки и другие объекты одновременно.

Ниже представлен подробный материал со всеми примерами на языке 1С.

 

Одномерный массив
Одномерный массив — это линейный список элементов.
• Пример: Список складов или список строк с наименованиями товаров ["Основной склад", "Розничный склад", "Склад брака"].
Многомерный массив
В 1С нет встроенного строгого многомерного массива (как в некоторых других языках), но многомерность реализуется путем создания массива массивов (когда элементом одного массива является другой массив).
• Пример: Матрица (таблица координат или ячеек), где строка сама содержит массив значений.

Как создать массив

Для создания пустого массива используется конструктор Новый Массив(). Также можно указать фиксированный размер, передав его в конструктор (хотя размер динамически расширяется методом Добавить).

Пример создания и заполнения одномерного и многомерного массивов:

// Создание обычного динамического массива

МассивСтрок = Новый Массив;

// Создание массива с предварительно выделенным размером (например, 5 элементов)

МассивФиксированногоРазмера = Новый Массив(5);

//Пример создания и заполнения одномерного и многомерного массивов:

// 1. Пример одномерного массива

ОдномерныйМассив = Новый Массив;

ОдномерныйМассив.Добавить("Яблоко");

ОдномерныйМассив.Добавить("Груша");

ОдномерныйМассив.Добавить("Слива");

// 2. Пример многомерного массива (массив массивов)

МногомерныйМассив = Новый Массив;

Строка1 = Новый Массив;

Строка1.Добавить(1);

Строка1.Добавить(2);

Строка2 = Новый Массив;

Строка2.Добавить(3);

Строка2.Добавить(4);

МногомерныйМассив.Добавить(Строка1);

МногомерныйМассив.Добавить(Строка2);

Создание массива фиксированной длины

(в параметрах конструктора передается количество элементов):

ФиксированныйМассив = Новый Массив(5); // Создаст массив из 5 элементов, заполненных значением Неопределено

Как обращаться к элементу массива

Доступ к элементам осуществляется по индексу в квадратных скобках [...]. Нумерация всегда начинается с 0.

 

ЗначениеЭлемента = ОдномерныйМассив[0]; // Получит "Яблоко"

// Обращение к элементу многомерного массива (строка 1, столбец 1 — второй элемент)

ЭлементМатрицы = МногомерныйМассив[0][1]; // Получит число 2

Как перебрать все элементы массива

Для обхода элементов используется цикл Для Каждого или классический цикл Для ... По по индексам.

 

// Обход через "Для Каждого"

Для Каждого Элемент Из ОдномерныйМассив Цикл

Сообщить(Элемент);

КонецЦикла;

// Обход по индексу

Для Индекс = 0 По ОдномерныйМассив.Владельцы - 1 Цикл // (или через .Количество() - 1)

Сообщить(ОдномерныйМассив[Индекс]);

КонецЦикла;

Как определить размер массива

Количество элементов в массиве узнают с помощью метода Количество().

 

РазмерМассива = ОдномерныйМассив.Количество();

Сообщить("Элементов в массиве: " + РазмерМассива);

 

Как удалить элемент массива

Удалить конкретный элемент можно по его индексу методом Удалить(Индекс).

 

// Удаляем первый элемент (с индексом 0)

ОдномерныйМассив.Удалить(0);

Как очистить массив

Метод Очистить() удаляет абсолютно все элементы из массива, делая его пустым.

 

ОдномерныйМассив.Очистить();

Сообщить(ОдномерныйМассив.Количество()); // Выведет 0

Как удалить повторяющиеся элементы массива

Простой и быстрый способ избавиться от дублей — загнать элементы в Соответствие или Таблицу Значений, либо использовать обход с проверкой. Удобнее всего использовать Соответствие:

 

ИсходныйМассив = Новый Массив;

ИсходныйМассив.Добавить("А");

ИсходныйМассив.Добавить("Б");

ИсходныйМассив.Добавить("А"); // дубль

ВременноеСоответствие = Новый Соответствие;

Для Каждого Элемент Из ИсходныйМассив Цикл

ВременноеСоответствие.Вставить(Элемент, Истина);

КонецЦикла;

ЧистыйМассив = Новый Массив;

Для Каждого КлючИЗначение Из ВременноеСоответствие Цикл

ЧистыйМассив.Добавить(КлючИЗначение.Ключ);

КонецЦикла;

Как скопировать массив

Метод Скопировать() создает поверхностную копию массива (новый объект-массив, содержащий те же ссылки на элементы).

 

КопияМассива = ОдномерныйМассив.Скопировать();

Как проверить, что два массива идентичны?

Прямого метода вроде Массив1.Идентичен(Массив2) в базовом API нет. Сравнение делают пошагово: проверяют совпадение размеров, а затем поэлементно сравнивают значения в цикле.

 

Функция МассивыИдентичны(Массив1, Массив2)

Если Массив1.Количество() <> Массив2.Количество() Тогда

Возврат Ложь;

КонецЕсли;

Для Индекс = 0 По Массив1.Количество() - 1 Цикл

Если Массив1[Индекс] <> Массив2[Индекс] Тогда

Возврат Ложь;

КонецЕсли;

КонецЦикла;

Возврат Истина;

КонецФункции


Как отсортировать массив по строчному значению

Чтобы отсортировать массив (например, содержащий строки или разнотипные данные, приводимые к строке), удобно использовать временную ТаблицуЗначений.

 

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Значение");

// Заполняем ТЗ данными из массива

Для Каждого Элемент Из ОдномерныйМассив Цикл

СтрокаТЗ = ТЗ.Добавить();

СтрокаТЗ.Значение = Элемент;

КонецЦикла;

// Сортируем колонку

ТЗ.Сортировать("Значение Возр");

// Переносим обратно в массив

ОдномерныйМассив.Очистить();

Для Каждого СтрокаТЗ Из ТЗ Цикл

ОдномерныйМассив.Добавить(СтрокаТЗ.Значение);

КонецЦикла;

Нюансы работы с Фиксированным Массивом

ФиксированныйМассив — это особый вид массива, главная особенность которого — неизменяемость (Read-only) после создания. Из него нельзя удалить элементы, нельзя добавить новые и нельзя перезаписать существующие.

1. Зачем он нужен?

* Безопасность конфигурации: Защита глобальных настроек или системных списков от случайного изменения разработчиком в процессе работы программы.

* Параметры функций: Часто используется платформой для возврата системных данных (например, параметры заполнения окон, списки ролей и т.д.).

 

2. Как создать Фиксированный Массив?

Его нельзя наполнить напрямую через методы Добавить(). Он всегда создается на основании уже существующего обычного массива.

 

// 1. Создаем и наполняем обычный массив

ОбычныйМассив = Новый Массив;

ОбычныйМассив.Добавить("Понедельник");

ОбычныйМассив.Добавить("Вторник");

// 2. На его основе создаем Фиксированный массив

ФиксМассив = Новый ФиксированныйМассив(ОбычныйМассив);

// Попытка изменить вызовет ОШИБКУ: "Метод объекта не обнаружен" или "Поле объекта недоступно для записи"

// ФиксМассив.Добавить("Среда"); // Ошибка!

// ФиксМассив[0] = "Воскресенье"; // Ошибка!

 

3. Как изменить данные в Фиксированном Массиве?

Если в ходе работы программы вам всё же потребовалось изменить состав фиксированного массива, алгоритм всегда один — «Распаковать, изменить, запаковать обратно»:

 

// 1. Конвертируем фиксированный массив обратно в обычный

МодифицируемыйМассив = Новый Массив(ФиксМассив);

// 2. Делаем любые изменения

МодифицируемыйМассив.Добавить("Среда");

// 3. Перезаписываем переменную новым фиксированным массивом

ФиксМассив = Новый ФиксированныйМассив(МодифицируемыйМассив);


4. Коварный нюанс: Мутабельность элементов

Фиксированный массив гарантирует, что нельзя изменить состав его элементов (удалить/добавить/заменить ссылку). Но если элементом фиксированного массива является изменяемый объект (например, обычный Массив или Структура), то внутренности этого объекта изменить можно.

 

ВнутреннийМассив = Новый Массив;

ВнутреннийМассив.Добавить("СтароеЗначение");

ВнешнийМассив = Новый Массив;

ВнешнийМассив.Добавить(ВнутреннийМассив);

// Создаем фиксированный массив

ФиксМассив = Новый ФиксированныйМассив(ВнешнийМассив);

// Проверяем:

// ФиксМассив[0] = Новый Массив; // ОШИБКА! Заменить элемент нельзя.

ФиксМассив[0].Добавить("НовоеЗначение"); // УСПЕШНО! Внутренний (обычный) массив изменился.

 

 

Вывод: ФиксированныйМассив делает неизменяемой только «внешнюю оболочку» (первый уровень вложенности). За этим нужно строго следить при проектировании структуры данных.

Передача массивов между клиентом и сервером

Передача данных между клиентским приложением (тонкий клиент, веб-клиент) и сервером — одна из самых частых задач в 1С. Массив является мультиплатформенным типом, что делает его идеальным контейнером для обмена информацией.

 

1. Доступность типа и сериализация

Обычный Массив доступен «везде»: и на Клиенте, и на Сервере. Когда вы передаете массив в качестве параметра серверного метода, платформа автоматически производит его сериализацию (превращает в поток данных, отправляет по сети и собирает обратно).

 

&НаКлиенте

Процедура ВыполнитьКоманду(Команда)

СписокКодов = Новый Массив;

СписокКодов.Добавить("00012");

СписокКодов.Добавить("00045");

// Передаем массив на сервер. Платформа берет расходы по сети на себя.

ОбработатьДанныеНаСервере(СписокКодов);

КонецПроцедуры

&НаСервереБезКонтекста

Процедура ОбработатьДанныеНаСервере(МассивКодов)

Для Каждого Код Из МассивКодов Цикл

// Обработка на сервере...

КонецЦикла;

КонецПроцедуры

 

 

2. Главное правило: Типизация элементов

Сам массив передается без проблем, но огромное значение имеет то, ЧТО находится внутри него.

* Если внутри массива примитивные типы (Строка, Число, Дата, Булево), пустые ссылки или ссылки на объекты БД (СправочникСсылка, ДокументСсылка), то массив успешно уйдет с клиента на сервер и наоборот.

* Если внутри массива находятся типы, доступные только на сервере (например, ДокументОбъект, Запрос, ВыборкаИзРезультатаЗапроса, ТаблицаЗначений), то при попытке вернуть такой массив на клиент или передать его через границу «Клиент-Сервер» система выдаст критическую ошибку (Ошибка вызова метода контекста / Ошибка сериализации).

 

3. Передача по ссылке (Входные параметры)

По умолчанию в 1С параметры в процедуры передаются по ссылке (ПоСсылка). Если на клиенте вы передали массив в процедуру НаСервере (контекстную), изменили его там (например, добавили элемент), то при возврате на клиент массив вернется уже измененным.

 

Совет: Для экономии трафика и ускорения работы, если массив большой и возвращать его измененным не нужно, используйте передачу по значению — ключевое слово Знач: Процедура ОбработатьДанные(Знач МойМассив).

Особенности работы с массивами в Запросах 1С

Запросы в 1С выполняются на стороне СУБД (SQL). Массив — это один из немногих объектов 1С, который можно передать внутрь запроса в качестве параметра для фильтрации данных.

1. Фильтрация по списку (Оператор В)

Если вам нужно выгрузить из базы данных только определенные товары или документы, их ссылки предварительно собирают в массив и передают в условие В (&ПараметрМассив).

 

// 1. Создаем и наполняем массив условий

МассивКлиентов = Новый Массив;

МассивКлиентов.Добавить(СсылкаПокупатель1);

МассивКлиентов.Добавить(СсылкаПокупатель2);

// 2. Создаем запрос

Запрос = Новый Запрос;

Запрос.Текст =

"

ВЫБРАТЬ | Продажи.Ссылка КАК Документ, | Продажи.СуммаДокумента КАК Сумма |ИЗ | Документ.РеализацияТоваровУслуг КАК Продажи |ГДЕ | Продажи.Контрагент В (&МассивКлиентов); // Используем оператор В

"

// 3. Устанавливаем массив в параметры

Запрос.УстановитьПараметр("МассивКлиентов", МассивКлиентов);

РезультатЗапроса = Запрос.Выполнить();

 

 

2. Важная ловушка: Пустой массив в запросе

Это самая частая архитектурная ошибка начинающих программистов, которая приводит к падению производительности всей системы.

* Как ведет себя 1С: Если в параметр &МассивКлиентов из примера выше передать пустой массив (в котором 0 элементов), СУБД воспримет условие В (&ПустойМассив) как Ложь. Запрос вернет пустой результат.

* В чем проблема: СУБД всё равно выполнит сканирование таблиц, тратя ресурсы сервера. Если запрос сложный, пустой массив может заставить SQL-сервер выбрать неоптимальный план выполнения, и система «зависнет».

* Правило хорошего тона (Best Practice): Перед запуском запроса всегда проверяйте массив на заполненность.

 

// 1. Создаем и наполняем массив условий

МассивКлиентов = Новый Массив;

МассивКлиентов.Добавить(СсылкаПокупатель1);

МассивКлиентов.Добавить(СсылкаПокупатель2);

// 2. Создаем запрос

Запрос = Новый Запрос;

Запрос.Текст =

"

ВЫБРАТЬ | Продажи.Ссылка КАК Документ, | Продажи.СуммаДокумента КАК Сумма |ИЗ | Документ.РеализацияТоваровУслуг КАК Продажи |ГДЕ | Продажи.Контрагент В (&МассивКлиентов); // Используем оператор В

"

// 3. Устанавливаем массив в параметры

Запрос.УстановитьПараметр("МассивКлиентов", МассивКлиентов);

РезультатЗапроса = Запрос.Выполнить();

 

3. Ограничения на размер массива в запросах

Хотя платформа 1С и СУБД (например, MS SQL или PostgreSQL) теоретически могут переварить массивы в десятки тысяч элементов, передавать огромные массивы в параметры запроса нельзя.

* Если в массиве будет более 20 000 – 50 000 элементов, запрос либо аварийно завершится с ошибкой SQL («Too many parameters»), либо начнет жутко тормозить.

* Решение: Если элементов очень много, их нужно загружать во Временную таблицу внутри запроса (через промежуточное создание Таблицы Значений и её индексацию), а не передавать обычным массивом через оператор В.

Массив, СписокЗначений или ТаблицаЗначений: что и когда выбирать?

Начинающие разработчики часто используют массив для всего подряд, но в 1С есть специализированные коллекции. Правильный выбор инструмента оптимизирует скорость работы программы и сокращает объём кода.

 

1. Когда использовать Массив (Массив)

Массив — это максимально «легковесный» и быстрый контейнер.

* Идеален для: Простых цепочек данных, передачи параметров в процедуры и функции, работы на клиенте, а также в качестве параметров для запросов.

* Минусы: Нет встроенной сортировки, нет поиска по сложным условиям, нельзя привязать визуальные свойства.

 

2. Когда использовать Список Значений (СписокЗначений)

Список значений — это массив «на стероидах», созданный в первую очередь для взаимодействия с пользователем.

Каждый элемент списка имеет не только Значение, но и Представление (текст, который видит юзер), Пометку (флажок-чекбокс) и Картинку.

Идеален для:

* Вывода пользователю меню выбора (метод ВыбратьЭлемент()).

* Организации списков с галочками (метод ОтметитьЭлементы()).

* Быстрой сортировки простых данных (СортироватьПоЗначению(), СортироватьПоПредставлению()).

 

Минусы: Более «тяжелый» для памяти, чем массив.

 

3. Когда использовать Таблицу Значений (ТаблицаЗначений)

Таблица значений — это полноценная база данных в оперативной памяти (состоит из колонок и строк).

Идеальна для: Сложных многомерных структур, где у одной записи есть много свойств (например, колонка «Товар», колонка «Количество», колонка «Цена»). Обладает мощнейшими методами: .НайтиСтроки(), .Скопировать(), .Итог(), .Свернуть().

Минусы: Категорически недоступна на Клиенте (в тонком и веб-клиенте). Передать её напрямую с сервера на клиент нельзя — вызовет ошибку сериализации.

 
 

 

📋 Универсальная коллекция - Список значений в 1С 8.3

Определение списока значений и примеры

Список значений в 1С 8.3 — это универсальная программная коллекция (объект встроенного языка), которая представляет собой пронумерованный набор элементов (ЭлементСписокЗначений), где каждый элемент хранит произвольное значение, а также может содержать представление (текст для пользователя), признак отметки (галочку) и картинку.

По принципу работы это аналог одномерного динамического массива.

Ниже представлена подробная статья-инструкция со всеми необходими примерами кода на языке 1С:Предприятие 8.3.

Что такое Список значений и как создать

Создается объект с помощью ключевого слова Новый

 

СписокКандидатов = Новый СписокЗначений;

Как добавить и вставить значение

Добавить (в конец списка): метод Добавить(<Значение>, <Представление>, <Пометка>, <Картинка>).

Вставить (на конкретную позицию по индексу): метод Вставить(<Индекс>, <Значение>, <Представление>, <Пометка>).

 

// Добавляем элементы в конец

СписокКандидатов.Добавить("Петров", "Петров П.П.");

СписокКандидатов.Добавить("Иванов", "Иванов И.И.");

// Вставляем элемент на первую позицию (индекс 0)

СписокКандидатов.Вставить(0, "Сидоров", "Сидоров С.С.");

Как перебрать значения в списке (обход)

Для обхода используется стандартный цикл Для Каждого ... Из ... Цикл:

 

Для Каждого ЭлементСписка Из СписокКандидатов Цикл

ЗначениеЭлемента = ЭлементСписка.Значение;

ПредставлениеТекст = ЭлементСписка.Представление;

Сообщить(ПредставлениеТекст + " : " + ЗначениеЭлемента);

КонецЦикла;

Как определить количество элементов

Свойство Количество() возвращает число элементов в списке:

 

Для Каждого ЭлементСписка Из СписокКандидатов Цикл

ВсегоЭлементов = СписокКандидатов.Количество();

Сообщить("В списке элементов: " + ВсегоЭлементов);

Как получить элемент по его индексу

Индексация начинается с 0:

 

Если СписокКандидатов.Количество() > 0 Тогда

ПервыйЭлемент = СписокКандидатов[0]; // или СписокКандидатов.Получить(0)

Сообщить("Первый элемент: " + ПервыйЭлемент.Представление);

КонецЕсли;

Как найти элемент в списке по его значению

Метод НайтиПоЗначению(<Значение>) возвращает первый найденный элемент или Неопределено:

 

НайденныйЭлемент = СписокКандидатов.НайтиПоЗначению("Иванов");

Если НайденныйЭлемент <> Неопределено Тогда

Сообщить("Найдено представление: " + НайденныйЭлемент.Представление);

КонецЕсли;

Как узнать индекс элемента в списке

Метод Индекс(<Элемент>) возвращает числовой индекс элемента:

 

Если НайденныйЭлемент <> Неопределено Тогда

ПозицияИндекс = СписокКандидатов.Индекс(НайденныйЭлемент);

Сообщить("Индекс элемента в списке: " + ПозицияИндекс);

КонецЕсли;

Как удалить элемент

Удалить можно по самому элементу или по его индексу методом Удалить():

 

Если НайденныйЭлемент <> Неопределено Тогда

ПозицияИндекс = СписокКандидатов.Индекс(НайденныйЭлемент);

Сообщить("Индекс элемента в списке: " + ПозицияИндекс);

КонецЕсли;

Как очистить список значений

Метод Очистить() удаляет абсолютно все элементы:

 

СписокКандидатов.Очистить();

Как отсортировать список по значению (или представлению)

Используются методы СортироватьПоЗначению() или СортироватьПоПредставлению() (можно передать направление сортировки НаправлениеСортировки.Убыв или Воср):

 

СписокКандидатов.СортироватьПоПредставлению(НаправлениеСортировки.Воср);

Как сдвинуть элемент в списке значений

Метод Сдвинуть(<Элемент>, <ВеличинаСмещения>) позволяет переместить элемент выше или ниже по списку:

 

// Сдвинуть первый элемент на 1 позицию вниз

Если СписокКандидатов.Количество() > 1 Тогда

ЭлементДляСдвига = СписокКандидатов[0];

СписокКандидатов.Сдвинуть(ЭлементДляСдвига, 1);

КонецЕсли;

Как сделать копию списка

Метод Скопировать() создает точную независимую копию объекта:

 

КопияСписка = СписокКандидатов.Скопировать();

Как выгрузить значения списка в массив и загрузить обратно

Выгрузить в массив: метод ВыгрузитьЗначения().

Загрузить из массива: метод ЗагрузитьЗначения(<Массив>).

 

// Выгрузка

МассивЗначений = СписокКандидатов.ВыгрузитьЗначения();

// Загрузка (заменяет текущие элементы списка элементами из массива)

СписокКандидатов.ЗагрузитьЗначения(МассивЗначений);

Интерактивная работа с пользователем (Выбор и Отметка)

Что такое модальный и немодальный режим?

* Модальный режим — блокирует работу пользователя со всем остальным интерфейсом 1С до тех пор, пока он не закроет открытое диалоговое окно (выберет значение или нажмет отмену). Примечание: в тонком и веб-клиенте модальные окна вызывают ограничения, поэтому рекомендуется использовать немодальные вызовы.

* Немодальный режим — не блокирует приложение; выполнение кода продолжается, а результат возвращается в специальную процедуру-обработчик (описание оповещения).

Как сделать немодальный выбор значения из списка

Пользователь кликает, окно не блокирует систему, а результат обрабатывается в процедуре ПослеВыбора:

 

// Вызов в клиентском контексте (на управляемой форме)

Процедура ВыбратьНемодально(Команда)

Оп = Новый ОписаниеОповещения("ПослеВыбора", ЭтотОбъект);

СписокКандидатов.ПоказатьВыборЗначения(Оп, "Выберите кандидата:");

КонецПроцедуры

Процедура ПослеВыбора(ЭлементСписка, ДополнительныеПараметры) Экспорт

Если ЭлементСписка <> Неопределено Тогда

Сообщить("Вы выбрали: " + ЭлементСписка.Значение);

Иначе

Сообщить("Выбор отменен.");

КонецЕсли;

КонецПроцедуры

Как сделать модальный выбор значения из списка

Устаревший подход (через функцию Выбрать), работает в основном на толстом клиенте или в серверном контексте старого образца:

 

ВыбранныйЭлемент = СписокКандидатов.Выбрать("Выберите значение");

Если ВыбранныйЭлемент <> Неопределено Тогда

Сообщить("Выбрано: " + ВыбранныйЭлемент.Значение);

КонецЕсли;

Как сделать немодальную отметку значений из списка

Позволяет пользователю расставить галочки (пометки) напротив нескольких элементов списка:

 

Процедура ОтметитьНемодально(Команда)

Оп = Новый ОписаниеОповещения("ПослеОтметки", ЭтотОбъект);

СписокКандидатов.ПоказатьОтметкуЗначений(Оп, "Отметьте нужных кандидатов:");

КонецПроцедуры

Процедура ПослеОтметки(СписокСОтметками, ДополнительныеПараметры) Экспорт

Если СписокСОтметками <> Неопределено Тогда

Для Каждого Эл Из СписокСОтметками Цикл

Если Эл.Пометка Тогда

Сообщить("Отмечен: " + Эл.Значение);

КонецЕсли;

КонецЦикла;

КонецЕсли;

КонецПроцедуры

Как сделать модальную отметку значений из списка

Открытие диалога с возможностью проставить пометки с остановкой выполнения кода:

 

Если СписокКандидатов.ОтметитьЗначения("Отметьте элементы") Тогда

Для Каждого Эл Из СписокКандидатов Цикл

Если Эл.Пометка Тогда

Сообщить("Пользователь отметил: " + Эл.Значение);

КонецЕсли;

КонецЦикла;

КонецЕсли;