ВИД (внешние источники данных) в 1С – это объекты конфигурации, позволяющие использовать информацию из внешних ODBC-источников (баз данных), не основанных на 1С:Предприятии, внутри прикладного решения так же, как будто бы она хранится в самой информационной базе.
В качестве ODBC-драйвера был выбран пакет FreeODBC, т.к. он бесплатный и его везде используют.
В процессе гугления использовались источники:
- Внешние источники данных на Linux-серверах 1С
- Настройка доступа к базе 1С на MSSQL из под Linux
- Настройка доступа к Microsoft SQL Server через ODBC. Ubuntu 12.04
- Пример интеграции базы 1С и внешней СУБД (хорошая статья)
- Подробное описание работы с ВИД (да и вообще хороший блог о работе с 1С)
- Программное добавление, изменение, удаление (примеры)
- Запись во внешний источник данных из 1С 8.3 (используя хранимые процедуры MS SQL Server)
- Запись во внешние источники данных в «1С:Предприятие 8» (используя хранимые процедуры MS SQL Server)
Установка
Достаточно установить пакет tdsodbc (разрядность должна совпадать с сервером 1С!):
(дополнительно установятся: libodbc1 odbcinst odbcinst1debian2)
1 |
$ apt install tdsodbc:i386 |
В файл odbcinst.ini добавить (если не добавилось автоматически) секцию для FreeTDS:
1 2 3 4 5 6 7 |
$ nano /etc/odbcinst.ini [FreeTDS] Description = FreeTDS Driver = <путь_к_либам>/libtdsodbc.so Setup = <путь_к_либам>/libtdsS.so FileUsage = 1 UsageCount = 1 |
, где <путь_к_либам_tdsodbc>:
- Для 32-битного пакета:
/usr/lib/i386-linux-gnu/odbc
- Для 64-битного пакета:
/usr/lib/x86_64-linux-gnu/odbc
Если этого не сделать, или поставить пакет не той же разрядности, что сервер 1С, то будет ошибка:
[unixODBC][Driver Manager]Can't open lib 'FreeTDS' : file not found
А вот такая ошибка будет, если неверно указали путь к либам:
/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so file not found
При нажатии на кнопку “…” конфигурация выдаст последний вскрик в виде окошка с ошибкой и благополучно покрашится. Что это за НЛО непонятно, но на нашем серваке оно поселилось, видать, надолго:
"Ошибка аутентификации клиента 1cv8 средствми операционной системы: Аутентификационный контекст клиента отсутствует в рабочем процессе"
Как я понял, поключаться и работать с ВИД можно двумя способами:
1) Подключаться программно.
Пример:
(Спасибо caponid за инфу о поле СУБД):
1 2 3 4 5 6 7 8 9 |
Соед = Новый ПараметрыСоединенияВнешнегоИсточникаДанных; Соед.СтрокаСоединения = "Строка_соединения"; Соед.АутентификацияОС = Ложь; Соед.ИмяПользователя = Пользователь; Соед.Пароль = Пароль; Соед.СУБД = "MSSQLServer"; //Явно указываем, потому что тот тип, что указали в строке соединения, игнорируется; Источник = ВнешниеИсточникиДанных["НазваниеИсточника"]; Источник.УстановитьПараметрыСоединенияСеанса(Соед); Источник.УстановитьСоединение(); |
Но тут у меня не получилось запихнуть проинициализированный объект ВИД в запрос:
1 2 3 4 5 6 7 |
Запрос.Текст = "ВЫБРАТЬ | Источник.Поле |ИЗ | &ВИД КАК Источник |"; Запрос.Параметры.Вставить("ВИД", ВИД); |
2) Использовать механизм подключения в режиме Предприятия. Параметры подключения хранятся тут:
РегистрСведений.НастройкиПодключенияКВнешнемуИсточникуДанных
или
Все функции -> Стандартные -> Управление внешними источниками данных
Строка подключения выглядит так:
"Driver={FreeTDS}; Server=SERVER,1433; Database=BASE; User Id=USER; Password=PASS;"
Пользователя и пароль я запихивал в отдельные поля.
Если в режиме предприятия будут отсутствовать параметры подключения к внешнему источнику данных, то будет ошибка:
"[unixODBC][Driver Manager]Data source name not found, and no default driver specified"
Названия Таблиц и полей в конфигураторе могут быть какими угодно, а вот к полям “Имя в источнике данных” нужно присмотреться внимательнее. Если в именах полей БД MS SQL есть, к примеру, символ “_”, то будет вот такая ошибочка:
"[FreeTDS][SQL Server]Incorrect syntax near 't_ticket_id'"
Спасибо master1c8.ru, выручил!
“Если значение, находящееся в свойстве Имя в источнике данных заключено в одинарные кавычки, то в SQL-запрос к базе данных это значение попадает без преобразований, вне зависимости от состава символов.”
Т.е. названия таблиц и полей MS SQL в поле “Имя в источнике данных” нужно указать в одинарных кавычках.
Дату нужно форматировать перед добавлением, например, так:
1 |
Формат(ТекущаяДата(), "ДФ='yyyy-MM-dd HH:mm:ss'") |
Иначе будет:
"[FreeTDS][SQL Server]Conversion failed when converting date and/or time from character string."
Для добавления новых записей поле идентификатора с автоинкременом нужно установить в “Только чтение”, иначе будет:
"[FreeTDS][SQL Server]Cannot insert explicit value for identity column in table 't_logs' when IDENTITY_INSERT is set to OFF."
При добавлении таблицы с помощью помощника, поля с внешними ключами (foreign_key) будут по-умолчанию устанавливаться в тип объекта, а не Число. Мне это небыло нужно, поэтому вручную менял тип.
Нужно быть внимательным с поиском записи с помощью функции НайтиПоПолю(). Значение должно совпадать с типом поля в таблице. Например, строку перегонять в число:
1 |
НайтиПоПолю("поле", Число(ЗначениеДляПоискаСтрока)); |
По поводу поиска вхождений записей в список значений в запросе:
table.id В(&СписокЗаявки) – не прокатит (СписокЗаявки – это СписокЗначений со значениями – строками, а id – число)
table.id В("+СтрокаЗаявки+") – прокатит (СтрокаЗаявки – строка со значениями через запятую)
Сейчас пишу и не понимаю почему не попробовал значения списка СписокЗаявки привести к численному типу, но проверять уже лень.
Чтобы не выводить таблицы в командный интерфейс раздела (подсистемы) в свойствах таблицы нужно убрать галку “Использовать стандартные команды“.
Что не получилось
Не получилось сделать поля выбора (а-ля combobox) с выпадающим списком значений из ВИД. Ставишь реквизиту формы тип таблицы ВИД, переносишь его на форму. Все ок, элемент (контрол) создается, но не отображается. Заморачиваться не стал, вводил вручную id-шники записи, этого было достаточно.
Выполнить хранимую процедуру. До этого хранимыми процедурами в БД не пользовался, хотя хорошая вещь.
Но как ни крутил я этот функционал в конфигураторе, ничего не вышло (а тут и тут работало).
Какие были ошибки…:
1) <Выражение в источнике данных>
2) <Ошибка>
1) FuncName
2) [FreeTDS][SQL Server]Invalid column name 'FuncName'.
1) dbo.FuncName
2) [FreeTDS][SQL Server]Cannot find either column "dbo" or the user-defined function or aggregate "dbo.FuncName", or the name is ambiguous.
1) SELECT <FuncName>
2) [FreeTDS][SQL Server]Incorrect syntax near the keyword 'SELECT'.
1) EXECUTE <FuncName>
2) [FreeTDS][SQL Server]Incorrect syntax near the keyword 'EXECUTE'.
1) * from dbo.FuncName()
2) Обращение к процедуре объекта как к функции (FuncName)
Так же не решился вопрос с кириллицей. А точнее, при создании записей из 1С в MS SQL текст на русском языке превращался в кракозябры, например:
" 0:@KB85 70O2:8 87 1!, ID=[3037]"
Параметры сортировки базы: Cyrillic_General_CI_AS.
Что пытался сделать:
1) настроить FreeTDS, всунув в его конфиг параметр charset в секцию [global]:
1 2 |
$ nano /etc/freetds/freetds.conf client charset = UTF8 |
2) добавить параметр charset в строку подключения:
"Driver={FreeTDS}; Server=SERVER,1433; Database=BASE; charset=UTF8;"
Не получилось. Еще есть вариант 3:
3) сменить API ODBC
Но придется делать все заново. Поэтому, ограничился записью текста на инглише.
Нужно больше прав!!!
При нехватке прав при выполнении запроса к таблицам ВИД будет ошибка:
Ошибка при вызове метода контекста (Выполнить): Недостаточно прав для работы с таблицей "ВнешнийИсточникДанных.БДTickets.Таблица.<TableName>"
Нужно добавить права:
На ВИД: Использование
На таблицы в запросе: Чтение
Для выполнения функции <ТаблицаВИД>.НайтиПоПолю() нужно добавить права (иначе “Нарушение прав доступа!”):
На ВИД: Использование
На таблицы в запросе: Чтение, Изменение
Для функции <ТаблицаВИД>.СоздатьОбъект() соответсвенно: Использование, Чтение и Добавление.
Кстати, стандартная роль “Запуск внешнего соединения” не понадобилась, для меня осталось загадкой ее назначение (разобраться не пытался).
Ну я решил проблему кирилицы при записи через процедуру в МуСкуле:
DELIMITER //
CREATE PROCEDURE perecodirovka ()
BEGIN
SET character_set_client =’cp1251′;
SET character_set_results =’utf8′;
SET collation_connection =’utf8_general_ci’;
END//
Потом в ВИД эту функцию добавляешь. И вызываешь при Подключении
И в строке подключения обязательно кодировку ср1251 указать.