COMSafeArray

Типы · COMSafeArray

Объектная оболочка над многомерным массивом 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 меняет число строк и нижнюю границу, сохраняет старые значения и не обещает содержимое новых ячеек.

Где и как запускать

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Собственная учебная база на Windows. Фрагмент вставьте в тело серверной процедуры ВыполнитьПример() Экспорт общего модуля УчебныеЗадачи, выполняемой на Windows.

  2. Все значения и COMSafeArray создаются самим примером в памяти. COMОбъект, Excel/Word, внешние компоненты, базы и сеть не используются.

  3. Запускайте три задачи отдельно. Размеры маленькие и фиксированные; не заменяйте их неограниченными значениями из внешнего API.

  4. Имена GetDimensions/GetValue/SetValue/Resize — реальные имена методов установленной справки, не придуманный английский перевод.

  5. Сверка 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);

Разбор по шагам

  1. Конструктор Из COMSafeArray копирует собственную исходную матрицу. Меняем ячейку копии и проверяем независимость оригинала.

  2. IsResizable проверяем до Resize. Метод допускает изменение только старшего, нулевого измерения и его нижней границы.

  3. Resize(3,−1) переносит старые две строки на индексы −1/0 и добавляет строку с индексом 1. Колонок по-прежнему две.

  4. Новые значения неопределённы. Мы не читаем их как нули, а сначала записываем 5/6.

  5. Resize(1,2) сокращает копию до одной первой строки с новым индексом 2. Данные остальных строк копии теряются; оригинал остаётся 2×2.

Как проверить результат

  1. Четырнадцать логических проверок дают Истина, если собственная матрица поддерживает Resize.

  2. После сокращения копия содержит одну строку 1/2 с индексом 2; исходная матрица всё ещё содержит 1/2 и 3/4.

Ожидаемый результат

Показаны независимое копирование, сохранение порядка при сдвиге границы и потеря данных при сокращении.

На что обратить внимание

  1. Resize не меняет число колонок второго измерения.

  2. Новые ячейки нельзя считать нулевыми без явной инициализации.

  3. Сокращение уничтожает лишние строки самой копии; это не фильтр с возможностью отмены.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Работать с индексами от −1 и 2, а не всегда от нуля

Матрица имеет две строки с индексами −1/0 и три колонки 2/3/4; показываем границы и обращение массивом индексов.

Где и как запускать

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Собственная учебная база на Windows. Фрагмент вставьте в тело серверной процедуры ВыполнитьПример() Экспорт общего модуля УчебныеЗадачи, выполняемой на Windows.

  2. Все значения и COMSafeArray создаются самим примером в памяти. COMОбъект, Excel/Word, внешние компоненты, базы и сеть не используются.

  3. Запускайте три задачи отдельно. Размеры маленькие и фиксированные; не заменяйте их неограниченными значениями из внешнего API.

  4. Имена GetDimensions/GetValue/SetValue/Resize — реальные имена методов установленной справки, не придуманный английский перевод.

  5. Сверка 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);

Разбор по шагам

  1. Конструктор Из массива 2 получает массив размеров и массив нижних границ. Их длина равна числу измерений.

  2. Число элементов равно 2/3, а максимальные индексы 0/4. Размер и верхняя граница — не одно и то же.

  3. Проверяем формулу верхняя − нижняя + 1. Циклы обходят именно GetLowerBound...GetUpperBound, не ошибочное 0...GetLength−1.

  4. По типу элемента 2 создаёт второй массив с теми же заданными границами. Каждую ячейку инициализируем перед чтением.

  5. SetValue(Индексы,77) и GetValue(Индексы) используют массив двух индексов в порядке старшее→младшее. Выгрузка — обычные массивы 1С с индексами от нуля.

Как проверить результат

  1. Одиннадцать проверок дают Истина; в собственной второй матрице ячейка [−1,2] стала 77, в исходной осталось 10.

  2. Выгрузка первой строки/колонки читается индексами 0/0, а не −1/2.

Ожидаемый результат

Показаны нестандартные границы и обе формы чтения/записи индексов без ошибочного предположения о нуле.

На что обратить внимание

  1. В массиве индексов должно быть ровно столько чисел, сколько измерений.

  2. Нижние границы COM не переносятся как отрицательные индексы обычного Массив 1С.

  3. Не путайте массив размеров с массивом самих данных.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.