Имя: Пароль:
1C
1С v8
Как поместить результат запроса в двухмерный массив
0 saf112
 
15.12.11
16:52
Здравствуйте.
Суть в том, что мне нужно вывести в эксель результат запроса, вида "Номер опоры, Тип опоры".
Я пытаюсь заполнить массив результатами выборки, перевести его в COMSafeArray и вывести в Range() на листе.

Проблема в том, что массив (2, н) -  не создается. А размерности я не знаю, этот код обернут еще в один цикл и прогоняется много раз.

В общем задача вот в чем - я обхожу все ЛЭП (Линии электро передач) и для каждой из них печатаю паспорт в эксель. в частности в этом паспорте есть раздел с опорами - их у каждой линии множество, и я вот таким вышеописанным образом пытаюсь их вывести.



//Получаем в "Опоры" список всех опор с их марками для выбранной ЛЭП
Запрос=Новый Запрос;
Запрос.Текст="
       |ВЫБРАТЬ СО_ОпорыВЛ.ДиспетчерскийНомер, СО_ОпорыВЛ.МаркаОпоры
   |ИЗ Справочник.СО_ОпорыВЛ КАК СО_ОпорыВЛ
   |ГДЕ
     |СО_ОпорыВЛ.Владелец = &ВЛ
   |УПОРЯДОЧИТЬ ПО СО_ОпорыВЛ.Ссылка
   |";
   Запрос.УстановитьПараметр("ВЛ", ВЛ.Ссылка);
   Опоры = Запрос.Выполнить().Выбрать();
       
   Лист.Cells(3, 6).Value = Строка(Опоры.Количество());
       
   i = 0;
   н =  Число(Опоры.Количество());

   Массив = Новый Массив(2, н);
   Пока Опоры.Следующий() Цикл
     Массив[0][i] = Строка(Опоры.ДиспетчерскийНомер);
     Массив[1][i] = Строка(Опоры.МаркаОпоры);
     i=i+1;
   КонецЦикла;    
       
   Массив2 = Новый COMSafeArray(Массив,"VT_BSTR");
   Лист.Range(Лист.Cells(3, 7), Лист.Cells(н, 8)).Value = Массив2;


Вот если че полный код - он не такой и большой

Процедура  ПридумаюНазвание()
   РабочийКаталог = "C:\ПаспортаВЛ\";
   
   //Инициализация Экселя
   Эксель = Новый COMОбъект("Excel.Application");
   Эксель.Application.Visible = Ложь;
   Книга = Эксель.WorkBooks.Open(РабочийКаталог+"Макет_ПаспортВЛ.xls");
   Лист = Книга.WorkSheets(4);
       
       
   //Получаем в "ВЛ" список всех нужных линий (по напряжению)
   Запрос=Новый Запрос;
   Запрос.Текст="
   |ВЫБРАТЬ СО.Ссылка, СО.Напряжение, СО.ДатаВвода, СО.Протяженность
   |ИЗ Справочник.СО КАК СО
   |ГДЕ
   |СО.ТипСО = &тип
   |И (СО.Напряжение = &напр1 ИЛИ СО.Напряжение = &напр2)
   |";
   Запрос.УстановитьПараметр("тип", Перечисления.СО_ТипыОбъектов.ЛЭП);
   Запрос.УстановитьПараметр("напр1", Справочники.Напряжения.НайтиПоКоду(10));
   Запрос.УстановитьПараметр("напр2", Справочники.Напряжения.НайтиПоКоду(9));
   ВЛ = Запрос.Выполнить();
   
   //Для отладки выводим на форму
   ЭлементыФормы.ТабличноеПоле1.Значение = ВЛ.Выгрузить();
   ЭлементыФормы.ТабличноеПоле1.СоздатьКолонки();
   
   
   //Обходим циклом все ЛЭП
   ВЛ = ВЛ.Выбрать();
   Пока ВЛ.Следующий() Цикл
       
   Лист.Cells(3, 1).Value = Строка(ВЛ.Напряжение);
   Лист.Cells(3, 2).Value = Формат(ВЛ.ДатаВвода, "ДФ = 'гггг'");
   Лист.Cells(3, 5).Value = Строка(ВЛ.Протяженность);
       
       
   //Получаем в "Опоры" список всех опор с их марками для выбранной ЛЭП
   Запрос=Новый Запрос;
   Запрос.Текст="
   |ВЫБРАТЬ СО_ОпорыВЛ.ДиспетчерскийНомер, СО_ОпорыВЛ.МаркаОпоры
   |ИЗ Справочник.СО_ОпорыВЛ КАК СО_ОпорыВЛ
   |ГДЕ
     |СО_ОпорыВЛ.Владелец = &ВЛ
   |УПОРЯДОЧИТЬ ПО СО_ОпорыВЛ.Ссылка
   |";
   Запрос.УстановитьПараметр("ВЛ", ВЛ.Ссылка);
   Опоры = Запрос.Выполнить().Выбрать();
       
   Лист.Cells(3, 6).Value = Строка(Опоры.Количество());
       
   i = 0;
   н =  Число(Опоры.Количество());
   Массив = Новый Массив(2, н);
   Пока Опоры.Следующий() Цикл
       Массив[0][i] = Строка(Опоры.ДиспетчерскийНомер);
       Массив[1][i] = Строка(Опоры.МаркаОпоры);
       i=i+1;
   КонецЦикла;
       
       
       
   Массив2 = Новый COMSafeArray(Массив,"VT_BSTR");
   Лист.Range(Лист.Cells(3, 7), Лист.Cells(н, 8)).Value = Массив2;
       
   //Сохраняем паспорт в экселевский файл
   Книга.SaveAs(РабочийКаталог+RegExp_Replace(Строка(ВЛ.Ссылка))+".xls");

КонецЦикла;
   
//Закрываем Эксель, освобождаем ресурсы
Эксель.Quit();
Эксель = 0;
   
КонецПроцедуры
1 Defender aka LINN
 
15.12.11
16:53
Я может кого сейчас опечалю, но в 1С массивы одномерные.
2 saf112
 
15.12.11
16:57
тут же на мисте встретил такой код, с указанием того, что он рабочий:


Попытка
   Эксель = Новый COMОбъект ("Excel.Application");
Исключение
   Возврат;
КонецПопытки;
Книга = Эксель.WorkBooks.Add();
Лист = Книга.WorkSheets(1);
Лист = Книга.Sheets.Add();
Массив=Новый массив (4,4);
   Массив[0][0]=2;    Массив[0][1]=1;    Массив[0][2]=1;    Массив[0][3]=4;
   Массив[1][0]=2;    Массив[1][1]=2;    Массив[1][2]=5;    Массив[1][3]=2;
   Массив[2][0]=0;    Массив[2][1]=3;    Массив[2][2]=3;    Массив[2][3]=0;
   Массив[3][0]=5;    Массив[3][1]=4;    Массив[3][2]=6;    Массив[3][3]=4.45;      
   Массив2 = Новый COMSafeArray(Массив,"VT_R8");
   Лист.Range(Лист.Cells(1,1),Лист.Cells(4,4)).Value=Массив2;
Попытка
   Книга.SaveAs();
Исключение
   Возврат;
КонецПопытки;


то есть, не такие они и одномерные)
3 Fish
 
гуру
15.12.11
17:00
(1) Да неужели? :))) Читаем и удивляемся:
А.П. Габец и Д.И. Гончаров (под редакцией М.Г. Радченко).

"1С:Предприятие 8.1. Простые примеры разработки"

   Как создать многомерный массив?

Массив является линейной динамической коллекцией с произвольным типом значений. Поэтому значениями массива могут выступать другие массивы.
То есть создание массива массивов и решает задачу создания многомерного массива.
Это можно делать при использовании конструктора массива (листинг 2.3) или в процессе добавления очередных элементов к массиву (листинг 2.4).

   Листинг 2.3. Создание многомерного массива

   ДвумерныйМассив = Новый Массив (2, 8);

   Листинг 2.4. Создание многомерного массива добавлением элементов

   ДвумерныйМассив = Новый Массив;
   МассивВторогоПорядка = Новый Массив (8);
   ДвумерныйМассив.Добавить(МассивВторогоПорядка);
   ДвумерныйМассив.Добавить(МассивВторогоПорядка);

И в том и в другом случае мы решим задачу создания двумерного массива размерностью 2х8.

Чтение и запись значений такого массива можно производить посредством директивного указания индексов (листинг 2.5) или при помощи метода Получить() (листинг 2.6).

   Листинг 2.5. Чтение массива с указанием индексов элемента

   Значение = ДвумерныйМассив[2][5];

   Листинг 2.6. Чтение массива с помощью метода Получить()

   Значение = ДвумерныйМассив.Получить(2).Получить(5);

Хотелось бы еще раз отметить, что создание массива определенной размерности конструктором ограничивает только количество возможных к заполнению значений массива, но не препятствует добавлению новых значений, в качестве которых могут выступать массивы произвольной размерности.
4 Fish
 
гуру
15.12.11
17:01
+(3) А еще инженер знаний. Стыдно должно быть :)))
5 saf112
 
15.12.11
17:05
(3) то есть, мне просто юзать "Добавить"? сейчас нет возможности попробовать, но похоже на решение, спасибо)
6 acsent
 
15.12.11
17:10
(1) ты с 77 попутал
7 Defender aka LINN
 
15.12.11
17:12
(6) Может быть, может быть... Все равно яя ими не пользовался :)