Объектная оболочка над многомерным массивом SAFEARRAY из COM. Позволяет создавать и использовать SAFEARRAY для обмена данными между COM-объектами. Для передачи массива в качестве параметра метода COM-объекта необходимо построить COMSafeArray нужной размерности с нужным типом элемента и указать построенный COMSafeArray в качестве значения входного параметра. Другие объекты 1С:Предприятия можно использовать в качестве значений входных параметров типа Массив только при наличии исчерпывающей информации о типах параметров в библиотеке типа COM-объекта. Результат метода COM-объекта или значение выходного параметра типа Массив всегда представляется объектом COMSafeArray.
Примеры платформы
Массив = Новый COMSafeArray("VT_I4", 2);
Массив.SetValue(0, 23);
Массив.SetValue(1, 13.5);
COMОбъект = Новый COMObject("ExampleCOMObject.ECOMClass");
COMОбъект.ProcessSafeArray(Массив);Полное описание, параметры и ограничения
COMSafeArray (COMSafeArray)
COMSafeArray (COMSafeArray)
Доступен, начиная с версии 8.0.
Методы:
GetDimensions (GetDimensions)
GetLength (GetLength)
GetLowerBound (GetLowerBound)
GetType (GetType)
GetUpperBound (GetUpperBound)
GetValue (GetValue)
IsResizable (IsResizable)
Resize (Resize)
SetValue (SetValue)
Выгрузить (Unload)
Конструкторы:
Из COMSafeArray
Из массива 1
Из массива 2
По типу элемента 1
По типу элемента 2
Описание:
Объектная оболочка над многомерным массивом SAFEARRAY из COM. Позволяет создавать и использовать SAFEARRAY для обмена данными между COM-объектами.
Для передачи массива в качестве параметра метода COM-объекта необходимо построить COMSafeArray нужной размерности с нужным типом элемента и указать построенный COMSafeArray в качестве значения входного параметра. Другие объекты 1С:Предприятия можно использовать в качестве значений входных параметров типа Массив только при наличии исчерпывающей информации о типах параметров в библиотеке типа COM-объекта.
Результат метода COM-объекта или значение выходного параметра типа Массив всегда представляется объектом COMSafeArray.
Доступность:
Тонкий клиент, сервер, толстый клиент, внешнее соединение.
Пример:
Массив = Новый COMSafeArray("VT_I4", 2);
Массив.SetValue(0, 23);
Массив.SetValue(1, 13.5);
COMОбъект = Новый COMObject("ExampleCOMObject.ECOMClass");
COMОбъект.ProcessSafeArray(Массив);
См. также:
COMSafeArray, конструктор Из COMSafeArray
Использование в версии:
Доступен, начиная с версии 8.0.
Методическая информация
Практические примеры
Скопировать матрицу и изменить только старшее измерение
Resize меняет число строк и нижнюю границу, сохраняет старые значения и не обещает содержимое новых ячеек.
Где и как запускать
Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.
Подготовка
Собственная учебная база на Windows. Фрагмент вставьте в тело серверной процедуры ВыполнитьПример() Экспорт общего модуля УчебныеЗадачи, выполняемой на Windows.
Все значения и COMSafeArray создаются самим примером в памяти. COMОбъект, Excel/Word, внешние компоненты, базы и сеть не используются.
Запускайте три задачи отдельно. Размеры маленькие и фиксированные; не заменяйте их неограниченными значениями из внешнего API.
Имена GetDimensions/GetValue/SetValue/Resize — реальные имена методов установленной справки, не придуманный английский перевод.
Сверка API/статические тесты не подтверждают фактическое выполнение COMSafeArray в установленной 1С.
Исходная = Новый COMSafeArray("VT_I4", 2, 2);
Исходная.SetValue(0, 0, 1);
Исходная.SetValue(0, 1, 2);
Исходная.SetValue(1, 0, 3);
Исходная.SetValue(1, 1, 4);
Копия = Новый COMSafeArray(Исходная);
Копия.SetValue(0, 0, 9);
Сообщить(Исходная.GetValue(0, 0) = 1);
Копия.SetValue(0, 0, 1);
Если Не Копия.IsResizable() Тогда
ВызватьИсключение "Собственная матрица не допускает Resize";
КонецЕсли;
Копия.Resize(3, -1);
Сообщить(Копия.GetLength(0) = 3);
Сообщить(Копия.GetLength(1) = 2);
Сообщить(Копия.GetLowerBound(0) = -1);
Сообщить(Копия.GetUpperBound(0) = 1);
Сообщить(Копия.GetValue(-1, 0) = 1);
Сообщить(Копия.GetValue(0, 1) = 4);
Копия.SetValue(1, 0, 5);
Копия.SetValue(1, 1, 6);
Сообщить(Копия.GetValue(1, 1) = 6);
Копия.Resize(1, 2);
Сообщить(Копия.GetLowerBound(0) = 2);
Сообщить(Копия.GetUpperBound(0) = 2);
Сообщить(Копия.GetValue(2, 0) = 1);
Сообщить(Копия.GetValue(2, 1) = 2);
Сообщить(Исходная.GetLength(0) = 2);
Сообщить(Исходная.GetValue(1, 1) = 4);Разбор по шагам
Конструктор Из COMSafeArray копирует собственную исходную матрицу. Меняем ячейку копии и проверяем независимость оригинала.
IsResizable проверяем до Resize. Метод допускает изменение только старшего, нулевого измерения и его нижней границы.
Resize(3,−1) переносит старые две строки на индексы −1/0 и добавляет строку с индексом 1. Колонок по-прежнему две.
Новые значения неопределённы. Мы не читаем их как нули, а сначала записываем 5/6.
Resize(1,2) сокращает копию до одной первой строки с новым индексом 2. Данные остальных строк копии теряются; оригинал остаётся 2×2.
Как проверить результат
Четырнадцать логических проверок дают Истина, если собственная матрица поддерживает Resize.
После сокращения копия содержит одну строку 1/2 с индексом 2; исходная матрица всё ещё содержит 1/2 и 3/4.
Ожидаемый результат
Показаны независимое копирование, сохранение порядка при сдвиге границы и потеря данных при сокращении.
На что обратить внимание
Resize не меняет число колонок второго измерения.
Новые ячейки нельзя считать нулевыми без явной инициализации.
Сокращение уничтожает лишние строки самой копии; это не фильтр с возможностью отмены.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Работать с индексами от −1 и 2, а не всегда от нуля
Матрица имеет две строки с индексами −1/0 и три колонки 2/3/4; показываем границы и обращение массивом индексов.
Где и как запускать
Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.
Подготовка
Собственная учебная база на Windows. Фрагмент вставьте в тело серверной процедуры ВыполнитьПример() Экспорт общего модуля УчебныеЗадачи, выполняемой на Windows.
Все значения и COMSafeArray создаются самим примером в памяти. COMОбъект, Excel/Word, внешние компоненты, базы и сеть не используются.
Запускайте три задачи отдельно. Размеры маленькие и фиксированные; не заменяйте их неограниченными значениями из внешнего API.
Имена GetDimensions/GetValue/SetValue/Resize — реальные имена методов установленной справки, не придуманный английский перевод.
Сверка API/статические тесты не подтверждают фактическое выполнение COMSafeArray в установленной 1С.
ИсходныеСтроки = Новый Массив;
Первая = Новый Массив;
Первая.Добавить(10);
Первая.Добавить(20);
Первая.Добавить(30);
Вторая = Новый Массив;
Вторая.Добавить(40);
Вторая.Добавить(50);
Вторая.Добавить(60);
ИсходныеСтроки.Добавить(Первая);
ИсходныеСтроки.Добавить(Вторая);
Размеры = Новый Массив;
Размеры.Добавить(2);
Размеры.Добавить(3);
НижниеГраницы = Новый Массив;
НижниеГраницы.Добавить(-1);
НижниеГраницы.Добавить(2);
Матрица = Новый COMSafeArray(ИсходныеСтроки, "VT_I4", Размеры, НижниеГраницы);
Сообщить(Матрица.GetLowerBound(0) = -1);
Сообщить(Матрица.GetUpperBound(0) = 0);
Сообщить(Матрица.GetLowerBound(1) = 2);
Сообщить(Матрица.GetUpperBound(1) = 4);
Сообщить(Матрица.GetUpperBound(1) - Матрица.GetLowerBound(1) + 1 = Матрица.GetLength(1));
Сообщить(Матрица.GetValue(-1, 2) = 10);
Сообщить(Матрица.GetValue(0, 4) = 60);
ЗаполненнаяКопия = Новый COMSafeArray("VT_I4", Размеры, НижниеГраницы);
Для НомерСтроки = Матрица.GetLowerBound(0) По Матрица.GetUpperBound(0) Цикл
Для НомерКолонки = Матрица.GetLowerBound(1) По Матрица.GetUpperBound(1) Цикл
ЗаполненнаяКопия.SetValue(НомерСтроки, НомерКолонки, Матрица.GetValue(НомерСтроки, НомерКолонки));
КонецЦикла;
КонецЦикла;
Индексы = Новый Массив;
Индексы.Добавить(-1);
Индексы.Добавить(2);
ЗаполненнаяКопия.SetValue(Индексы, 77);
Сообщить(ЗаполненнаяКопия.GetValue(Индексы) = 77);
Сообщить(ЗаполненнаяКопия.GetValue(-1, 2) = 77);
Сообщить(Матрица.GetValue(-1, 2) = 10);
Выгрузка = Матрица.Выгрузить();
Сообщить(Выгрузка.Получить(0).Получить(0) = 10);Разбор по шагам
Конструктор Из массива 2 получает массив размеров и массив нижних границ. Их длина равна числу измерений.
Число элементов равно 2/3, а максимальные индексы 0/4. Размер и верхняя граница — не одно и то же.
Проверяем формулу верхняя − нижняя + 1. Циклы обходят именно GetLowerBound...GetUpperBound, не ошибочное 0...GetLength−1.
По типу элемента 2 создаёт второй массив с теми же заданными границами. Каждую ячейку инициализируем перед чтением.
SetValue(Индексы,77) и GetValue(Индексы) используют массив двух индексов в порядке старшее→младшее. Выгрузка — обычные массивы 1С с индексами от нуля.
Как проверить результат
Одиннадцать проверок дают Истина; в собственной второй матрице ячейка [−1,2] стала 77, в исходной осталось 10.
Выгрузка первой строки/колонки читается индексами 0/0, а не −1/2.
Ожидаемый результат
Показаны нестандартные границы и обе формы чтения/записи индексов без ошибочного предположения о нуле.
На что обратить внимание
В массиве индексов должно быть ровно столько чисел, сколько измерений.
Нижние границы COM не переносятся как отрицательные индексы обычного Массив 1С.
Не путайте массив размеров с массивом самих данных.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.