8.х V82.COMConnector как обратиться к свойствам реквизита?

Тема в разделе "Отчеты и обработки для "1С:Предприятие 8"", создана пользователем cvmbackup, 2 май 2012.

  1. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Вопрос не в языке написания кода, а в универсальности по отношению к объектам. Т.е. запрос будет производится к любому объекту с любым количеством реквизитов и любыми именами этих реквизитов! Необходимо перебрать все реквизиты и их значения и вывести в MEMO

    Реквизит1 - Значение
    Реквизит2 - Значение
    ...
  2. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    vartanet, как перебирать объекты и их реквизиты через Метаданные ТС сам написал еще в первом посте. Вопрос сейчас у ТС в другом.
  3. Tiger86
    Offline

    Tiger86 Модераторы Команда форума Модератор

    Регистрация:
    24 мар 2011
    Сообщения:
    6.407
    Симпатии:
    108
    Баллы:
    104
    а вы в своем первоначальном коде не пробовали обратиться вот не так
    Код:
    znachenie:=doc[doc_rekv.имя];
    а так
    Код:
    znachenie:=doc_rekv.имя;
    ведь по идее doc_rekv - это уже полученный реквизит в вашем коде....
  4. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Tiger86, так не получится. Так вернет имя реквизита, а не значение реквизита с таким именем в конкретном документе.
  5. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Походу придется возится с индексами, что не есть удобно.
  6. mialord
    Offline

    mialord Модераторы Команда форума Модератор

    Регистрация:
    31 июл 2009
    Сообщения:
    5.398
    Симпатии:
    40
    Баллы:
    54
    Либо так znachenie:=doc[string(doc_rekv.имя)];
    либо так znachenie:=doc[V8Connect.Строка(doc_rekv.имя)]Что-то в таком виде. Т.е. извлеките саму строку, я писал из 1С там отработал метод Строка(), не знаю отработает ли String
  7. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Ну не терпит delphi квадратные скобки!!!!
    В этом то вся и проблема. Если бы было возможно их как то заменить, я бы использовал код из первого вопросительного поста данной темы.

    Вот опять квадратные скобки!!!

    Начал создавать динамический запрос:

    текдок=Документы.ТестовыйДокумент.НайтиПоНомеру("000000001");
    ИмяТекдок = текдок.Метаданные().Имя;

    ТекстЗапроса = "ВЫБРАТЬ ";

    Если текдок.Метаданные().Реквизиты.Количество() > 0 Тогда
    Для Сч = 0 По текдок.Метаданные().Реквизиты.Количество() - 1 Цикл
    ТекстЗапроса=ТекстЗапроса+ИмяТекдок+"."+текдок.Метаданные().Реквизиты.Получить(Сч).Имя;
    Если Сч<>текдок.Метаданные().Реквизиты.Количество() - 1 Тогда ТекстЗапроса=ТекстЗапроса+", "; КонецЕсли;
    КонецЦикла;
    КонецЕсли;


    Если текдок.Метаданные().ТабличныеЧасти.Количество() > 0 Тогда
    Для СчТаб = 0 По текдок.Метаданные().ТабличныеЧасти.Количество() - 1 Цикл

    ТЧ=текдок.Метаданные().ТабличныеЧасти.Получить(СчТаб);
    ТекстЗапроса=ТекстЗапроса+" "+ИмяТекдок+"."+ТЧ.Имя+".(";

    Для СчТабРекв = 0 По текдок.Метаданные().ТабличныеЧасти
    [ТЧ.Имя].Реквизиты.Количество() - 1 Цикл

    КонецЦикла;

    КонецЦикла;
    КонецЕсли;


    И снова эти грабли!!! Как обойти квадратные скобки??????
    Нужно перечислить все реквизиты табличной части! (без использования квадратных скобок)
  8. Tiger86
    Offline

    Tiger86 Модераторы Команда форума Модератор

    Регистрация:
    24 мар 2011
    Сообщения:
    6.407
    Симпатии:
    108
    Баллы:
    104
    вам уже говорили, что через квадратные скобки идет обращение к элементам массива. Только внутри должен быть индекс, а не строка. Получается, что можно использовать и квадратные скобки, но надо обращаться через индексы.
  9. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Рабочий пример на 1С без использования скобок. На делфи думаю не составить труда перевести. Ну и сделать нормально, выделить все что нужно в отдельную процедуру.

    Код:
     КОМСоединитель = Новый COMОбъект(СоединенияИБ.ИмяCOMСоединителя());
    Соединение = КОМСоединитель.Connect(СтрокаСоединения);
    
    
    НомерДокумента = "ТДК00000008";
    КОМДокумент = Соединение.Документы.РеализацияТоваровУслуг.НайтиПоНомеру(НомерДокумента);
    РеквизитыКОМДокумента = КОМДокумент.Метаданные().Реквизиты;
    ТабличныеЧастиКОМДокумента = КОМДокумент.Метаданные().ТабличныеЧасти;
    
    ТекстЗапроса = "";
    
    ТекстЗапроса = "ВЫБРАТЬ ";
    СчетчикЦикла = 0;
    Для СчетчикЦикла = 0 По РеквизитыКОМДокумента.Count() - 1 Цикл
    ТекстЗапроса = ТекстЗапроса + " Документ." + Соединение.String(РеквизитыКОМДокумента.Получить(СчетчикЦикла).Имя) + ", ";
    КонецЦикла;
    ТекстЗапроса = Лев(ТекстЗапроса, СтрДлина(ТекстЗапроса) - 2);
    ТекстЗапроса = ТекстЗапроса + " ИЗ Документ.РеализацияТоваровУслуг КАК Документ ГДЕ Документ.Номер = &НомерДокумента";
    
    КОМЗапрос = Соединение.NewObject("Запрос");
    КОМЗапрос.Текст = ТекстЗапроса;
    КОМЗапрос.УстановитьПараметр("НомерДокумента", НомерДокумента);
    КОМРезультат = КОМЗапрос.Выполнить();
    КОМТЗ = КОМРезультат.Выгрузить();
    
    СчетчикЦикла = 0;
    Для СчетчикЦикла = 0 По КОМТЗ.Колонки.Count() - 1 Цикл
    Поле = Соединение.String(КОМТЗ.Колонки.Получить(СчетчикЦикла).Имя);
    ЗначениеПоля = Соединение.String(КОМТЗ.Получить(0).Получить(СчетчикЦикла));
    Сообщить("Реквизит: " + Поле + "   -   " + ЗначениеПоля);
    КонецЦикла;
    
    
    СчетчикЦикла = 0;
    Для СчетчикЦикла = 0 По ТабличныеЧастиКОМДокумента.Count() - 1 Цикл
    ТабличнаяЧасть = ТабличныеЧастиКОМДокумента.Получить(СчетчикЦикла);
    РеквизитыТабличнойЧасти = ТабличнаяЧасть.Реквизиты;
    
    ТекстЗапроса = "ВЫБРАТЬ ";
    СчетчикЦикла = 0;
    Для СчетчикЦикла = 0 По РеквизитыТабличнойЧасти.Count() - 1 Цикл
    ТекстЗапроса = ТекстЗапроса + " ДокументТЧ." + Соединение.String(РеквизитыТабличнойЧасти.Получить(СчетчикЦикла).Имя) + ", ";
    КонецЦикла;
    ТекстЗапроса = Лев(ТекстЗапроса, СтрДлина(ТекстЗапроса) - 2);
    ТекстЗапроса = ТекстЗапроса + " ИЗ Документ.РеализацияТоваровУслуг." + Соединение.String(ТабличнаяЧасть) + " КАК ДокументТЧ ГДЕ ДокументТЧ.Ссылка.Номер = &НомерДокумента";
    
    КОМЗапрос = Соединение.NewObject("Запрос");
    КОМЗапрос.Текст = ТекстЗапроса;
    КОМЗапрос.УстановитьПараметр("НомерДокумента", НомерДокумента);
    КОМРезультат = КОМЗапрос.Выполнить();
    КОМТЗ = КОМРезультат.Выгрузить();
    
    СчетчикЦикла = 0;
    Для СчетчикЦикла = 0 По КОМТЗ.Колонки.Count() - 1 Цикл
    Поле = Соединение.String(КОМТЗ.Колонки.Получить(СчетчикЦикла).Имя);
    ЗначениеПоля = Соединение.String(КОМТЗ.Получить(0).Получить(СчетчикЦикла));
    Сообщить("Реквизит табличной части: " + Поле + "   -   " + ЗначениеПоля);
    КонецЦикла;
    КонецЦикла;
    
    Соединение = Неопределено;
    
  10. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Ну вот видно что человек разбирается в языке. И понимает суть проблеммы!
    СПАСИБО !!! +100500 раз.
  11. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Выкладываю рабочий код на DELPHI если кому понадобится:

    естественно сначало соединяемся с базой 1С через CreateOleObject('V82.COMConnector')

    Рабочий код в этом сообщении

    Результат в memo забиваются все реквизиты документа и реквизиты всех табличных частей с их хначениями.
  12. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Не за что.

    На всякий случай уточню: делал копипастом для быстроты. Во второй части кода (там где идет вывод значений табличной части) - вывод только для первой строки этой табличной части.

    Т.е. надо будет этот вывод обернуть в еще один цикл по строкам (количеству строк в полученной ТЧ), и соответственно здесь:
    Код:
     ЗначениеПоля = Соединение.String(КОМТЗ.Получить(0).Получить(СчетчикЦикла));
    уже будет:
    Код:
     ЗначениеПоля = Соединение.String(КОМТЗ.Получить( <СчетчикВнешнегоЦикла> ).Получить(СчетчикЦикла));
    Upd:
    Упс... Оказывается уже и код на дэлфи готов..
  13. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Сейчас попробую, сам тестил на тестовом документе где одна строка в табличной части забита ))))
  14. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Пипец я НУБ в 1С !!!
    Немогу найти как получить количество строк табличной части для создания цикла.
    На ум приходит только это
    Код:
    КоличествоСтрок=КОМДокумент[ТабличнаяЧасть.Имя].Количество();
    но там опять эти гавенные квадратные скобки :wall:
  15. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Рабочий допиленный код на DELPHI :

    естественно сначало соединяемся с базой 1С через CreateOleObject('V82.COMConnector')

    Рабочий код в этом сообщении.

    Считаю проблему решенной и тему можно закрывать!
    Благодарю shurikvz
  16. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Код:
      zapros_txt := 'ВЫБРАТЬ НомерСтроки ИЗ Документ.'+doc_name+'.' + tab_part_name;
    zapros.Текст := zapros_txt;
    zapros_result := zapros.Выполнить();
    zapros_tab_num := zapros_result.Выбрать();
    Это лишнее. Убрать.

    Строку
    Код:
    for y := 0 to zapros_tab_num.Count() - 1 do begin
    соответственно переписать на
    Код:
    for y := 0 to zapros_tab.Count() - 1 do begin
  17. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Я думал при таком тексте запроса
    ТекстЗапроса = ТекстЗапроса + " ДокументТЧ." + String(РеквизитыТабличнойЧасти.Получить(СчетчикЦикла).Имя) + ", ";
    в выборку попадают только реквизиты ТЧ, а не все строки ТЧ.
  18. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Переделал но выкладывать не буду, а то флуд какой то получается, уже третий листинг кода с небольшими поправками. Кому нужно тот догадается что удалить а что добавить.
    shurikvz ещё раз спасибо.
    .
  19. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Нашел ошибку в коде, перебор табличных частей документа не производится, счетчики циклов необходимо сделать уникальными.
  20. TopicStarter Overlay
    cvmbackup
    Offline

    cvmbackup

    Регистрация:
    13 фев 2012
    Сообщения:
    39
    Симпатии:
    0
    Баллы:
    1
    Для 1С
    Код:
    НомерДокумента = "000000001";
    КОМДокумент = Документы.ТестовыйДокумент.НайтиПоНомеру(НомерДокумента);
    РеквизитыКОМДокумента = КОМДокумент.Метаданные().Реквизиты;
    ТабличныеЧастиКОМДокумента = КОМДокумент.Метаданные().ТабличныеЧасти;
    Сообщить(КОМДокумент.Метаданные().Имя);
    ТекстЗапроса = "";
    ТекстЗапроса = "ВЫБРАТЬ ";
    СчетчикЦикла = 0;
    Для СчетчикЦикла = 0 По РеквизитыКОМДокумента.Count() - 1 Цикл
    ТекстЗапроса = ТекстЗапроса + " Документ." + String(РеквизитыКОМДокумента.Получить(СчетчикЦикла).Имя) + ", ";
    КонецЦикла;
    ТекстЗапроса = Лев(ТекстЗапроса, СтрДлина(ТекстЗапроса) - 2);
    ТекстЗапроса = ТекстЗапроса + " ИЗ Документ.ТестовыйДокумент КАК Документ ГДЕ Документ.Номер = &НомерДокумента";
    КОМЗапрос = Новый Запрос();
    КОМЗапрос.Текст = ТекстЗапроса;
    КОМЗапрос.УстановитьПараметр("НомерДокумента", НомерДокумента);
    КОМРезультат = КОМЗапрос.Выполнить();
    КОМТЗ = КОМРезультат.Выгрузить();
    СчетчикЦикла = 0;
    Для СчетчикЦикла = 0 По КОМТЗ.Колонки.Count() - 1 Цикл
    Поле = String(КОМТЗ.Колонки.Получить(СчетчикЦикла).Имя);
    ЗначениеПоля = String(КОМТЗ.Получить(0).Получить(СчетчикЦикла));
    Сообщить("Реквизит: " + Поле + "   -   " + ЗначениеПоля);
    КонецЦикла;
    
    Для СчТЧ = 0 По ТабличныеЧастиКОМДокумента.Count() -1 Цикл
    ТабличнаяЧасть = ТабличныеЧастиКОМДокумента.Получить(СчТЧ);
    РеквизитыТабличнойЧасти = ТабличнаяЧасть.Реквизиты;
    ТекстЗапроса = "ВЫБРАТЬ ";
    СчетчикЦикла = 0;
    Для СчТЧРекв = 0 По РеквизитыТабличнойЧасти.Count() - 1 Цикл
    ТекстЗапроса = ТекстЗапроса + " ДокументТЧ." + String(РеквизитыТабличнойЧасти.Получить(СчТЧРекв).Имя) + ", ";
    КонецЦикла;
    ТекстЗапроса = Лев(ТекстЗапроса, СтрДлина(ТекстЗапроса) - 2);
    ТекстЗапроса = ТекстЗапроса + " ИЗ Документ.ТестовыйДокумент." + String(ТабличнаяЧасть) + " КАК ДокументТЧ ГДЕ ДокументТЧ.Ссылка.Номер = &НомерДокумента";
    КОМЗапрос = Новый Запрос();
    КОМЗапрос.Текст = ТекстЗапроса;
    КОМЗапрос.УстановитьПараметр("НомерДокумента", НомерДокумента);
    КОМРезультат = КОМЗапрос.Выполнить();
    КОМТЗ = КОМРезультат.Выгрузить();
    Для КолТЧ = 0 По КОМТЗ.Количество() - 1 Цикл
    Для СчТЧКолонки = 0 По КОМТЗ.Колонки.Count() - 1 Цикл
    Поле = String(КОМТЗ.Колонки.Получить(СчТЧКолонки).Имя);
    ЗначениеПоля = String(КОМТЗ.Получить(КолТЧ).Получить(СчТЧКолонки));
    Сообщить("Реквизит "+ТабличнаяЧасть+": " + Поле + "   -   " + ЗначениеПоля);
    КонецЦикла;
    КонецЦикла;
    КонецЦикла;
    



    Для DELPHI
    PHP:
    var
    izy:Integer;
    docdoc_rekvtab_chastizaproszapros_resultzapros_tabzapros_tab_numtab_parttab_rekvOleVariant;
    doc_numdoc_namerekvizitznacheniezapros_txttab_part_name:string;
    begin
    Memo1
    .Lines.Clear;
    doc_num:='000000001';
    doc:=V8Connect.Документы.ТестовыйДокумент.НайтиПоНомеру(doc_num);
    doc_rekv := doc.Метаданные().Реквизиты;
    tab_chasti := doc.Метаданные().ТабличныеЧасти;
    doc_name:=doc.Метаданные().Имя;
    zapros_txt := 'ВЫБРАТЬ ';
    for 
    := 0 to doc_rekv.Count() - do begin
    zapros_txt 
    := zapros_txt ' Документ.' String(doc_rekv.Получить(i).Имя);
    if 
    i<doc_rekv.Count() - 1 then zapros_txt:=zapros_txt+', ';
    end;
    zapros_txt := zapros_txt ' ИЗ Документ.'+doc_name+' КАК Документ ГДЕ Документ.Номер = &НомерДокумента';
    zapros := V8Connect.NewObject('Запрос');
    zapros.Текст := zapros_txt;
    zapros.УстановитьПараметр('НомерДокумента'doc_num);
    zapros_result := zapros.Выполнить();
    zapros_tab := zapros_result.Выгрузить();
    for 
    := 0 to zapros_tab.Колонки.Count() - do begin
    rekvizit 
    := String(zapros_tab.Колонки.Получить(i).Имя);
    znachenie := String(zapros_tab.Получить(0).Получить(i));
    Memo1.Lines.Add('Реквизит документа: '+rekvizit+' - '+znachenie);
    end;
    for 
    := 0 to tab_chasti.Count() - do begin
    tab_part 
    := tab_chasti.Получить(i);
    tab_rekv := tab_part.Реквизиты;
    tab_part_name:=tab_part.Имя;
    zapros_txt := 'ВЫБРАТЬ ';
    for 
    := 0 to tab_rekv.Count() - do begin
    zapros_txt 
    := zapros_txt ' ДокументТЧ.' String(tab_rekv.Получить(z).Имя);
    if 
    z<tab_rekv.Count() - 1 then zapros_txt:=zapros_txt+', ';
    end;
    zapros_txt := zapros_txt ' ИЗ Документ.'+doc_name+'.' tab_part_name' КАК ДокументТЧ ГДЕ ДокументТЧ.Ссылка.Номер = &НомерДокумента';
    zapros.Текст := zapros_txt;
    zapros.УстановитьПараметр('НомерДокумента'doc_num);
    zapros_result := zapros.Выполнить();
    zapros_tab := zapros_result.Выгрузить();
    for 
    := 0 to zapros_tab.Count() - do begin
    for := 0 to zapros_tab.Колонки.Count() - do begin
    rekvizit 
    := String(zapros_tab.Колонки.Получить(z).Имя);
    znachenie := String(zapros_tab.Получить(y).Получить(z));
    Memo1.Lines.Add('Реквизит '+String(tab_part.Имя)+': '+rekvizit+' - '+znachenie);
    end;
    end;
    end;
    end;

Поделиться этой страницей