7.7 Данные из 1С в sql

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 7.7"", создана пользователем punkyklan, 19 июл 2013.

  1. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Здравствуйте, у меня есть такой вопрос можно ли данные из 1Ски вытаскивать и записывать их в таблицы sql напрямую?
  2. Yuriy_Alexandrovich
    Offline

    Yuriy_Alexandrovich Профессионал в 1С Команда форума

    Регистрация:
    15 сен 2011
    Сообщения:
    1.275
    Симпатии:
    76
    Баллы:
    54
    Посмотрите тут _http://habrahabr.ru/post/164913/
    _http://habrahabr.ru/post/166559/
  3. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    а что в программном коде в 1С 7.7 прописать, чтоб данные записывать в sql?
  4. Yuriy_Alexandrovich
    Offline

    Yuriy_Alexandrovich Профессионал в 1С Команда форума

    Регистрация:
    15 сен 2011
    Сообщения:
    1.275
    Симпатии:
    76
    Баллы:
    54
    Извеняюсь, указанные ссылки для 8.2, в 7.7 нужно будет подключать COM объекты
    в поисковики много дают по этому вопросу
  5. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Ткните носом пожалуйста, в том примере указано только как обращаться к sql и брать данные из sql, а мне необходимо их туда записывать или я все таки не вижу и опять ткните носом пожалуйста.
    Поисковики выдают как настраивать 1С и SQL, я ввожу в поисковике "данные из 1С 7.7 в sql".
  6. Tiger86
    Offline

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

    Регистрация:
    24 мар 2011
    Сообщения:
    6.407
    Симпатии:
    108
    Баллы:
    104
    вот самая первая ссылка гугла _http://www.sql.ru/forum/699769/chtenie-i-zapis-dannyh-iz-1s-7-7-v-bd-ms-sql-2005
  7. Yuriy_Alexandrovich
    Offline

    Yuriy_Alexandrovich Профессионал в 1С Команда форума

    Регистрация:
    15 сен 2011
    Сообщения:
    1.275
    Симпатии:
    76
    Баллы:
    54
    Код:
    // подключение к базе данных
    MSSQL = Подключение(ПараметрыПодключения);
    // набор записей
    Запрос = Новый COMОбъект("ADODB.RecordSet");
    // текст запроса
    ТекстЗапроса = "Update " + ИмяТаблицы + " SET <поле таблицы> = '" + ЗначениеПоля+ "' WHERE " + УсловияОтбора;
    //ТекстЗапроса = "Update " + ИмяТаблицы + " SET <поле таблицы> = '" + ЗначениеПоля + "'";
    // исполнение запроса
    Запрос = MSSQL.Execute(ТекстЗапроса);
    
  8. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Я попробую
  9. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Прямые запросы к MS SQL серверу


    На днях была реализована следующая задача: создание таблицы/загрузка данных в базу на MS SQL из 1С, считывание данных из MS SQL в 1С. Реализация сделана с использованием COM-соединения. Обновиться до 14й платформы и организовать все с помощью внешних источников данных по ряду причин было невозможно. А теперь обо всем по порядку.

    1. Настройки для MS SQL.
    Создаем новую DataBase (пусть будет testDB) через консоль SQL, дополнительные настройки настройки по желанию. Я не стал создавать из 1С через скрипт, потому что:
    а) процедура разовая;
    б) для этого пришлось бы хранить логин/пароль администратора SQL в 1С.
    Создаем отдельного пользователя SQL с полными правами в нашей DataBase (допустим, имя пользователя com1c). Для этого в форме настроек пользователя на вкладке "Server Roles" оставляем все как есть, по умолчанию доступна роль "public" - только просмотр. На вкладке "User Mapping" находим нашу DataBase, добавляем роль db_owner. Пароль пользователя зависит от настроек политики безопасности сервера.

    2. Создание/загрузка через 1С.
    Для начала нам нужно подключиться к нашей DataBase и создать в ней таблицу (test_table в моем примере). Для этого нам нужна строка подключения для создания COM-соединения в 1С. Я нашел примеры различных строк на <a href="http://www.connectionstrings.com/">http://www.connectionstrings.com/. Необходимые скрипты SQL можно получить из консоли, если при создании нового объекта нажать кнопку "Script" вверху формы настроек объекта, мои скрипты получены именно таким образом. Пишем код процедуры:

    СтрокаПодключения =
    "Provider=SQLOLEDB.1;
    |User ID=com1c;
    |Pwd=********;
    |Data Source=Имя_сервера_SQL;
    |Initial Catalog= testDB"
    ;//наша database

    Connection = Новый COMОбъект("ADODB.Connection");
    Command = Новый COMОбъект("ADODB.Command");
    RecordSet = Новый COMОбъект("ADODB.RecordSet");

    Попытка
    Connection.Open(СокрЛП(СтрокаПодключения));
    Command.ActiveConnection = Connection;
    //Проверка на наличие нашей database
    Command.CommandText = "select * from sys.databases where name = 'testDB'";
    RecordSet = Command.Execute();

    Если RecordSet.EOF() И RecordSet.BOF() Тогда
    //нет записей - нет такой database, надо создавать;
    Возврат;
    КонецЕсли;

    RecordSet.MoveFirst();
    Исключение
    Сообщить(ОписаниеОшибки());
    КонецПопытки;

    //создание/удаление таблицы. в файле загрузки несколько миллионов записей, поэтому было решено пересоздавать таблицу заново, нежели удалять записи.
    Command.CommandText =
    "USE testDB
    |IF exists(select name from sys.objects Where name = 'test_table' And type = 'U') drop table [dbo].[test_table]"
    ;
    Command.Execute();

    Command.CommandText =
    "USE testDB
    |Create table test_table (
    |POLE_01 VARCHAR (4),
    |POLE_02 DATE,
    |POLE_03 Numeric(9,0),
    |)"
    ;
    Command.Execute();

    //Создаем индексы, несколько миллионов записей после этого будут обрабатываться быстрее

    Command.CommandText =
    "USE testDB
    |CREATE NONCLUSTERED INDEX [NumSer] ON [dbo].[test_table]
    |(
    |[POLE_01] ASC
    |) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]"
    ;
    Command.Execute();

    //заполенение происходит из файла dbf

    ФайлДБФ = Новый XBase(ФайлДанных);
    ФайлДБФ.Кодировка=КодировкаXBase.OEM;
    КолЗаписей = ФайлДБФ.КоличествоЗаписей();
    ФайлДБФ.Первая();

    Для сч = 1 По КолЗаписей Цикл
    Command.CommandText =
    "USE testDB
    |INSERT INTO test_table VALUES(
    |'"
    +ДБФ.POLE_01+"',
    |'"
    +ДБФ.POLE_02 +"',
    |'"
    +ДБФ.POLE_03 +"',
    |)"
    ;
    Command.Execute();
    ФайлДБФ.Следующая();
    КонецЦикла;

    ФайлДБФ.ЗакрытьФайл();
    Command = Неопределено;
    Connection = Неопределено;
    RecordSet = Неопределено;
    3. Поиск через 1С.
    Подключение к базе приводить не буду, можно взять из кода выше, рассмотрим создание/обработку запроса.

    Command.CommandText = "SELECT * FROM [testDB].[dbo].[test_table] WHERE POLE_01= '"+Поле_01+"' AND POLE_02 = '"+POLE_02+"'" ;
    //сначала пробовал этот запрос, в консоли SQL он так же работает, но в 1С после выполнения соединение закрывается, вылетает с ошибкой Operation is not allowed when object is closed
    //|USE "+ testDB +";
    //|SELECT * FROM test_table WHERE POLE_01 = '"+Поле_01+"' AND POLE_02 = '"+Поле_02+"';";

    RecordSet = Новый COMОбъект("ADODB.RecordSet");

    Попытка
    RecordSet = Command.Execute();
    Если RecordSet.EOF() И RecordSet.BOF() Тогда
    Сообщить("По заданным условиям ничего не найдено.");
    Возврат Неопределено;
    КонецЕсли;

    мСтруктура = Новый Структура;
    мПоля = RecordSet.Fields.Count - 1;
    //в моем случае запрос возвращает либо одну запись, либо ничего. для обхода записей можно использовать Пока НЕ RecordSet.EOF() Цикл
    RecordSet.MoveFirst();

    Для сч = 0 По мПоля Цикл
    мСтруктура.Вставить(RecordSet.Fields(сч).Name, RecordSet.Fields(сч).Value);
    КонецЦикла;

    //из SQL дата возвращается строкой ГГГГ-ММ-ДД, преобразуем в дату
    мСтруктура. POLE_02 = Дата(СтрЗаменить(мСтруктура. POLE_02, "-", ""));

    Возврат мСтруктура;

    Исключение
    Сообщить(ОписаниеОшибки());
    Возврат Неопределено;
    КонецПопытки; На этом все, в дальнейшем думаю реализовать что-нибудь подобное с помощью объекта 1С "Внешние источники данных", будет весело :)
  10. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Подскажите что не так, он мне в sql записывает все одинаковые записи и не переходит на следующую

    Процедура Выполнить()
    Перем Запрос,ТекстЗапроса1,ТекстЗапроса2,ТекстЗапроса3,к,к1,Rs,фио,н,Соединение,ИДишник;
    Соединение=СоздатьОбъект("ADODB.Connection");
    Соединение.Open("Provider=SQLOLEDB;Data Source=172.31.90.100;Initial Catalog=Portal_test;User ID=sa;Password=12233445");
    Если Соединение.State=1 Тогда
    Рез=СоздатьОбъект("ADODB.Recordset");
    Рез.ActiveConnection=Соединение;
    Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса =

    "//{{ЗАПРОС(Сформировать)
    |Сотрудники = Справочник.Сотрудники.ТекущийЭлемент;
    |Наименование = Справочник.Сотрудники.Наименование;
    |Родитель = Справочник.Сотрудники.Родитель;

    |Группировка Сотрудники Без Групп Без Упорядочивания;
    |Без Итогов;
    |"//}}ЗАПРОС ;
    ;

    Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
    Предупреждение(ОписаниеОшибки()+"Не выполнен запрос!");
    Возврат;
    КонецЕсли;
    н=1;
    Пока Запрос.Группировка() = 1 Цикл
    фио=строка(Запрос.Фамилия+" "+Запрос.Имя+" "+Запрос.Отчество);
    ТекстЗапроса = "Update Pers_sotr1 SET FIO='" +строка(фио)+"'";
    н=н+1;
    конецесли;
    конеццикла;
    Рез = Соединение.Execute(ТекстЗапроса);
    сообщить(н);
    Соединение.Close();
    Иначе
    Сообщить(описаниеошибки()+"Не удалось установить соединение");
    возврат;
    Конецпроцедуры


    Как мне в sql записать все записи?
  11. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Код:
    	  
    Пока Запрос.Группировка() = 1 Цикл 
    фио=строка(Запрос.Фамилия+" "+Запрос.Имя+" "+Запрос.Отчество); 
    ТекстЗапроса = "Update Pers_sotr1 SET FIO='" +строка(фио)+"'";
    н=н+1;
    //конецесли; Это еще что?
    Рез = Соединение.Execute(ТекстЗапроса); //вне цикла вызов был
    конеццикла;
    
    сообщить(н);
    
  12. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    вне цикла вызывала, результат тот же самый
  13. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    а должен быть внутри. как в примере
  14. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Пока Запрос.Группировка() = 1 Цикл
    фио=строка(Запрос.Фамилия+" "+Запрос.Имя+" "+Запрос.Отчество);
    ТекстЗапроса = "Update Pers_sotr1 SET FIO='" +строка(фио)+"'";
    Рез = Соединение.Execute(ТекстЗапроса);
    конеццикла;
    Вот так вы имеете ввиду?
  15. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
  16. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Код:
    Процедура Выполнить()
    Перем Запрос,ТекстЗапроса,фио,рез,Соединение;
    Соединение=СоздатьОбъект("ADODB.Connection");
    Соединение.Open("Provider=SQLOLEDB;Data Source=172.31.90.100;Initial Catalog=Portal_test;User ID=sa;Password=12233445");
    Если Соединение.State=1 Тогда
    Рез=СоздатьОбъект("ADODB.Recordset");
    Рез.ActiveConnection=Соединение;
    Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса =
    "//{{ЗАПРОС(Сформировать)
    |Сотрудники = Справочник.Сотрудники.ТекущийЭлемент;
    |Фамилия = Справочник.Сотрудники.Фамилия;
    |Имя = Справочник.Сотрудники.Имя;
    |Отчество = Справочник.Сотрудники.Отчество;
    |Группировка Сотрудники Без Групп Без Упорядочивания;
    |Без Итогов;
    |"//}}ЗАПРОС ;
    ;
    Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
    Предупреждение(ОписаниеОшибки()+"Не выполнен запрос!");
    Возврат;
    КонецЕсли;
    Пока Запрос.Группировка() = 1 Цикл
    фио=строка(Запрос.Фамилия+" "+Запрос.Имя+" "+Запрос.Отчество);
    ТекстЗапроса = "Update Pers_sotr1 SET FIO='" +строка(фио)+"'";
    Рез = Соединение.Execute(ТекстЗапроса);
    конеццикла;
    Соединение.Close();
    Иначе
    Сообщить(описаниеошибки()+"Не удалось установить соединение");
    возврат;
    КонецЕсли;
    Конецпроцедуры
    Вот именно так он записывает только одну фамилию во все строки таблицы sql
    Помогите пожалуйста, что не так
  17. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Пыталась записать сначала всех сотрудников в Таблицу значений, туда записывает нормально, а в sql записывает во все строки таблицы последнего сотрудника из таблицы значений
  18. TopicStarter Overlay
    punkyklan
    Offline

    punkyklan Опытный в 1С

    Регистрация:
    12 дек 2012
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Пробую по другому, очищаю таблицу в sql, записываю записи, записывает нормально, ног выдает ошибку на sql String or binary data would be truncated. и не записывает в таблицу больше 281 записи, как этого избежать?

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