Имя: Пароль:
1C
1С v8
Ошибка сом объекта ADODB.Command
,
0 SherifSP
 
21.03.14
18:16
Пытаюсь прямым запросом выбрать данные справочника номенклатура и тут тебе на, ошибка: {Форма.Форма.Форма(39)}: Поле объекта не обнаружено (Execute)
    RS = Cmd.Execute;

Connection = Новый COMОбъект("ADODB.Connection");
    Cmd = Новый COMОбъект("ADODB.Command");
    ConnectionString="Provider=SQLOLEDB.1;Password="+СокрЛП(Пароль)+"; Persist Security Info=True; User ID="+
    СокрЛП(Логин)+"; Initial Catalog="+СокрЛП(База)+"; Data Source="+СокрЛП(Сервер);
    Connection.ConnectionTimeOut =30;
    Connection.CursorLocation = 3;
    Попытка
        Если Connection.State=0 Тогда
            Connection.Open(ConnectionString);
        КонецЕсли;
    Исключение
        Предупреждение("Невозможно установить Соединение!"+РазделительСтрок+
        "Проверте параметры соединения"+РазделительСтрок+
        "(Возможно 1С включена в монопольном режиме)");
        Возврат;
    КонецПопытки;
    
    Cmd.ActiveConnection = Connection;
    // --- считываем первую запись для получения идентификаторов полей в таблице-----
    Cmd.CommandText ="Select top 1 * from "+ СокрЛП(Таблица);
    RS = Новый COMОбъект("ADODB.RecordSet");
    RS = Cmd.Execute;
1 SherifSP
 
21.03.14
18:16
+(0) В последней строке ошибка
2 kiruha
 
21.03.14
18:18
Execute()
код из vb что ли ?
3 Torquader
 
21.03.14
18:19
(1) Так там и в предпоследней что-то не то делается - зачем создавать объект, если его потом затрут другим.
4 SherifSP
 
21.03.14
18:24
(3) Продолжение кода

Для А=0 По rs.Fields.Count-1 Цикл
        ТЗ.Колонки.Добавить(RS.Fields(А).Name);
    КонецЦикла ;
    Cmd.CommandText ="Select count (*) from "+ СокрЛП(Таблица);
    RSC = СоздатьОбъект("ADODB.RecordSet");
    RSC= Cmd.Execute;
    ВыгрЗаписей=rsc.Fields(0).Value;
    СтатусСтрока="Всего записей: "+rsc.Fields(0).Value; Форма.Обновить();
    RSC.Close();
5 SherifSP
 
21.03.14
18:30
(2) Работает)
6 SherifSP
 
21.03.14
18:35
"Select top 1 * from Reference116" это текст запроса, ошибка теперь другая
Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): Недопустимое имя объекта "Reference116".

Хотя такая таблица в базе 1С sql есть
7 Torquader
 
21.03.14
18:36
(6) А права на неё есть ?
8 Torquader
 
21.03.14
18:36
(4) Строка
RSC = СоздатьОбъект("ADODB.RecordSet");
точно не нужна - без неё всё также будет работать, только быстрее.
9 ДенисЧ
 
21.03.14
18:37
_Reference116
10 ДенисЧ
 
21.03.14
18:37
Если это 1с база
11 SherifSP
 
21.03.14
18:55
(9) Получается что к колонка тамблицы тоже нужно обращатся с символом _, типа _Code ?
12 Torquader
 
21.03.14
19:01
(11) Проще через Studio зайти в sql-базу и посмотреть всё, что там есть, а уже потом писать запросы.
13 ДенисЧ
 
21.03.14
19:02
(11) Получается, что нужно знать, как точно поля называются, а не гадать...
14 МихаилМ
 
21.03.14
19:08
RS = Новый COMОбъект("ADODB.RecordSet");
    RS = Cmd.Execute;

это бред
15 Torquader
 
21.03.14
19:12
(14) Это "дословный" перевод с VBA выражения:
Dim RS as ADODB.RecordSet
Set RS=Cmd.Execute

Просто там определение типа переменной ускоряет работу, так как вызовы идут через Vtbl, а не через запрос имени метода перед вызовом.

Просто 1С не умеет делать вызовы через Vtbl и предварительное описание объектов, так что здесь тип переменной ничего не даст.
16 SherifSP
 
21.03.14
19:13
Читал в интернете что прямые запросы быстрее отрабатывают нежели обычные, решил протестировать:

Connection = Новый COMОбъект("ADODB.Connection");
    Cmd = Новый COMОбъект("ADODB.Command");
    ConnectionString="Provider=SQLOLEDB.1;Password="+СокрЛП(Пароль)+"; Persist Security Info=True; User ID="+
    СокрЛП(Логин)+"; Initial Catalog="+СокрЛП(База)+"; Data Source="+СокрЛП(Сервер);
    Connection.ConnectionTimeOut =30;
    Connection.CursorLocation = 3;
    Попытка
        Если Connection.State=0 Тогда
            Connection.Open(ConnectionString);
        КонецЕсли;
    Исключение
        Предупреждение("Невозможно установить Соединение!"+РазделительСтрок+
        "Проверте параметры соединения"+РазделительСтрок+
        "(Возможно 1С включена в монопольном режиме)");
        Возврат;
    КонецПопытки;
    
    Cmd.ActiveConnection = Connection;
    // --- считываем первую запись для получения идентификаторов полей в таблице-----
    //Cmd.CommandText ="Select top 1 * from "+ СокрЛП(Таблица);
    
    ТекДат = ТекущаяДата();
    Для I = 1 По 100 Цикл
        ТекстЗапроса =  "
        |SELECT
        |    Spr._Code as Код,
        |    Spr._Description as Наименование
        |FROM
        |    _Reference116 as Spr";
        
        RS = Новый COMОбъект("ADODB.RecordSet");
        Cmd.CommandText = ТекстЗапроса;
        RS = Cmd.Execute();
    КонецЦикла;
    Сообщить(ТекущаяДата()-ТекДат);
    
    ТекДат = ТекущаяДата();
    Для I = 1 По 100 Цикл
       ТекстЗапроса = "
       |ВЫБРАТЬ
       |    Номенклатура.Код,
       |    Номенклатура.Наименование
       |ИЗ
       |    Справочник.Номенклатура КАК Номенклатура";
       Запрос = Новый Запрос(ТекстЗапроса);
       Результат = Запрос.Выполнить().Выгрузить();
    КонецЦикла;
    Сообщить(ТекущаяДата() - ТекДат);

И что меня больше всего поразило, первый запрос отработал за 24 секунды, а второй за 6 секунд, как так?
17 Torquader
 
21.03.14
19:16
(16) Не забывай, что на доступ к объектам ADO тоже расходуется время и засекать нужно время выполнения самого запроса, а не выбора и обхода результата.
18 SherifSP
 
21.03.14
19:18
(17) А как проверить время выполнения самого запроса?
19 SherifSP
 
21.03.14
19:24
Ожидал я от прямых запросов большего
20 Torquader
 
21.03.14
19:40
(18) Время выполнения команды Execute будет время выполнения запроса и время создания объекта recordset, если стоит выгружать данные сразу, если нет - то запрос выполняется в процессе запроса данных - это в любом случае медленнее, чем в 1С, где данные запроса получаются сразу, а потом хранятся в памяти 1С.
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.