Первый шаг в 1С — абсолютно бесплатно.
Определение массива и примеры Массив в 1С 8.3 — это универсальная пронумерованная коллекция значений произвольного типа, где элементы располагаются друг за другом и доступны по индексу (начиная с 0). В одном массиве можно хранить значения разные по типу: ссылки на документы, числа, строки и другие объекты одновременно. Ниже представлен подробный материал со всеми примерами на языке 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. Перезаписываем переменную новым фиксированным массивом ФиксМассив = Новый ФиксированныйМассив(МодифицируемыйМассив);
Фиксированный массив гарантирует, что нельзя изменить состав его элементов (удалить/добавить/заменить ссылку). Но если элементом фиксированного массива является изменяемый объект (например, обычный Массив или Структура), то внутренности этого объекта изменить можно.
ВнутреннийМассив = Новый Массив; ВнутреннийМассив.Добавить("СтароеЗначение"); ВнешнийМассив = Новый Массив; ВнешнийМассив.Добавить(ВнутреннийМассив); // Создаем фиксированный массив ФиксМассив = Новый ФиксированныйМассив(ВнешнийМассив); // Проверяем: // ФиксМассив[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. |
Что такое Список значений и как создать Создается объект с помощью ключевого слова Новый
СписокКандидатов = Новый СписокЗначений; |
Как добавить и вставить значение Добавить (в конец списка): метод Добавить(<Значение>, <Представление>, <Пометка>, <Картинка>). Вставить (на конкретную позицию по индексу): метод Вставить(<Индекс>, <Значение>, <Представление>, <Пометка>).
// Добавляем элементы в конец СписокКандидатов.Добавить("Петров", "Петров П.П."); СписокКандидатов.Добавить("Иванов", "Иванов И.И."); // Вставляем элемент на первую позицию (индекс 0) СписокКандидатов.Вставить(0, "Сидоров", "Сидоров С.С."); |
Как перебрать значения в списке (обход) Для обхода используется стандартный цикл Для Каждого ... Из ... Цикл:
Для Каждого ЭлементСписка Из СписокКандидатов Цикл ЗначениеЭлемента = ЭлементСписка.Значение; ПредставлениеТекст = ЭлементСписка.Представление; Сообщить(ПредставлениеТекст + " : " + ЗначениеЭлемента); КонецЦикла; |
Как определить количество элементов Свойство Количество() возвращает число элементов в списке:
Для Каждого ЭлементСписка Из СписокКандидатов Цикл ВсегоЭлементов = СписокКандидатов.Количество(); Сообщить("В списке элементов: " + ВсегоЭлементов); |
Как получить элемент по его индексу Индексация начинается с 0:
Если СписокКандидатов.Количество() > 0 Тогда ПервыйЭлемент = СписокКандидатов[0]; // или СписокКандидатов.Получить(0) Сообщить("Первый элемент: " + ПервыйЭлемент.Представление); КонецЕсли; |
Как найти элемент в списке по его значению Метод НайтиПоЗначению(<Значение>) возвращает первый найденный элемент или Неопределено:
НайденныйЭлемент = СписокКандидатов.НайтиПоЗначению("Иванов"); Если НайденныйЭлемент <> Неопределено Тогда Сообщить("Найдено представление: " + НайденныйЭлемент.Представление); КонецЕсли; |
Как узнать индекс элемента в списке Метод Индекс(<Элемент>) возвращает числовой индекс элемента:
Если НайденныйЭлемент <> Неопределено Тогда ПозицияИндекс = СписокКандидатов.Индекс(НайденныйЭлемент); Сообщить("Индекс элемента в списке: " + ПозицияИндекс); КонецЕсли; |
Как удалить элемент Удалить можно по самому элементу или по его индексу методом Удалить():
Если НайденныйЭлемент <> Неопределено Тогда ПозицияИндекс = СписокКандидатов.Индекс(НайденныйЭлемент); Сообщить("Индекс элемента в списке: " + ПозицияИндекс); КонецЕсли; |
Как очистить список значений Метод Очистить() удаляет абсолютно все элементы:
СписокКандидатов.Очистить(); |
Как отсортировать список по значению (или представлению) Используются методы СортироватьПоЗначению() или СортироватьПоПредставлению() (можно передать направление сортировки НаправлениеСортировки.Убыв или Воср):
СписокКандидатов.СортироватьПоПредставлению(НаправлениеСортировки.Воср); |
Как сдвинуть элемент в списке значений Метод Сдвинуть(<Элемент>, <ВеличинаСмещения>) позволяет переместить элемент выше или ниже по списку:
// Сдвинуть первый элемент на 1 позицию вниз Если СписокКандидатов.Количество() > 1 Тогда ЭлементДляСдвига = СписокКандидатов[0]; СписокКандидатов.Сдвинуть(ЭлементДляСдвига, 1); КонецЕсли; |
Как сделать копию списка Метод Скопировать() создает точную независимую копию объекта:
КопияСписка = СписокКандидатов.Скопировать(); |
Как выгрузить значения списка в массив и загрузить обратно Выгрузить в массив: метод ВыгрузитьЗначения(). Загрузить из массива: метод ЗагрузитьЗначения(<Массив>).
// Выгрузка МассивЗначений = СписокКандидатов.ВыгрузитьЗначения(); // Загрузка (заменяет текущие элементы списка элементами из массива) СписокКандидатов.ЗагрузитьЗначения(МассивЗначений); |
Интерактивная работа с пользователем (Выбор и Отметка) Что такое модальный и немодальный режим? * Модальный режим — блокирует работу пользователя со всем остальным интерфейсом 1С до тех пор, пока он не закроет открытое диалоговое окно (выберет значение или нажмет отмену). Примечание: в тонком и веб-клиенте модальные окна вызывают ограничения, поэтому рекомендуется использовать немодальные вызовы. * Немодальный режим — не блокирует приложение; выполнение кода продолжается, а результат возвращается в специальную процедуру-обработчик (описание оповещения). |
Как сделать немодальный выбор значения из списка Пользователь кликает, окно не блокирует систему, а результат обрабатывается в процедуре ПослеВыбора:
// Вызов в клиентском контексте (на управляемой форме) Процедура ВыбратьНемодально(Команда) Оп = Новый ОписаниеОповещения("ПослеВыбора", ЭтотОбъект); СписокКандидатов.ПоказатьВыборЗначения(Оп, "Выберите кандидата:"); КонецПроцедуры Процедура ПослеВыбора(ЭлементСписка, ДополнительныеПараметры) Экспорт Если ЭлементСписка <> Неопределено Тогда Сообщить("Вы выбрали: " + ЭлементСписка.Значение); Иначе Сообщить("Выбор отменен."); КонецЕсли; КонецПроцедуры |
Как сделать модальный выбор значения из списка Устаревший подход (через функцию Выбрать), работает в основном на толстом клиенте или в серверном контексте старого образца:
ВыбранныйЭлемент = СписокКандидатов.Выбрать("Выберите значение"); Если ВыбранныйЭлемент <> Неопределено Тогда Сообщить("Выбрано: " + ВыбранныйЭлемент.Значение); КонецЕсли; |
Как сделать немодальную отметку значений из списка Позволяет пользователю расставить галочки (пометки) напротив нескольких элементов списка:
Процедура ОтметитьНемодально(Команда) Оп = Новый ОписаниеОповещения("ПослеОтметки", ЭтотОбъект); СписокКандидатов.ПоказатьОтметкуЗначений(Оп, "Отметьте нужных кандидатов:"); КонецПроцедуры Процедура ПослеОтметки(СписокСОтметками, ДополнительныеПараметры) Экспорт Если СписокСОтметками <> Неопределено Тогда Для Каждого Эл Из СписокСОтметками Цикл Если Эл.Пометка Тогда Сообщить("Отмечен: " + Эл.Значение); КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры |
Как сделать модальную отметку значений из списка Открытие диалога с возможностью проставить пометки с остановкой выполнения кода:
Если СписокКандидатов.ОтметитьЗначения("Отметьте элементы") Тогда Для Каждого Эл Из СписокКандидатов Цикл Если Эл.Пометка Тогда Сообщить("Пользователь отметил: " + Эл.Значение); КонецЕсли; КонецЦикла; КонецЕсли; |
|