Подключение к 1С 77 через внешний источник данных, работа со справочниками 77 (на примере справочника клиенты)
- Добавление внешнего источника данных
Шаг 1
Шаг 2 (заполняем основные свойства внешнего соединения)
Шаг 3 (добавление данных)
Чтобы добавить источник данных удобнее добавить новую таблицу, 1С предложить либо добавить вручную, либо выбрать из списка таблиц источника данных – выбираем из источника)
Шаг 4 (добавляем строку соединения с источником данных)
Для добавления строки соединения лучше нажать на кнопку «…» справа от поля «Строка соединения:»
Внимание!!! Сохраните данную строку подключения (например в notepad), она понадобится в дальнейшем!!!
Если мы сделали все правильно, то 1С выведет нам список таблиц базы данных. Нас интересует справочник 77 «Клиенты». У меня это таблица SC46.
2. Подключение справочника
1С корректно определила, что данная таблица – это объектные данные и выбрала все реквизиты данной таблицы (справочника). Для упрощения работы нам будут нужны следующие:
ROWID – уникальный идентификатор записи в таблице SQL
ID – уникальный идентификатор объекта 1С (это будет поле ключа)
PARENTID – идентификатор родителя
CODE – реквизит «Код» 1С77 элемента справочника
DESCR – реквизит «Наименование» 1С77 элемента справочника (это будет поле представления)
ISFOLDER – признак элемент/группа 1С77 справочника
И нажимаем «Готово»
Попробуем посмотреть, что же у нас получилось… Запускаем 1С в режиме предприятия…
Выбираем нашу таблицу «dbo.SC46»… И 1С просит ввести имя пользователя и пароль для подключения к внешнему источнику…
Ну что ж… Вводим, через нажатие кнопки «Общие параметры». Вот тут то нам и пригодится сохраненная в notepad строка подключения…
Обновляем нашу таблицу, и результат конечно есть, но стремненько…
Попробуем сделать так, что бы вид нашей таблицы не отличался от вида стандартного справочника 1С82
3. Настройка вида справочника из внешнего источника
Шаг 1 (настраиваем имя таблицы)
Шаг 2 (настраиваем поля таблицы)
Особо уделю внимание полю PARENTID. Это же ссылка на родителя. Значит необходимо поменять тип значения со строки (9) на ссылочный тип данных из внешнего источника
Шаг 3 (смотрим результат)
Уже конечно лучше, скажем так на троечку…
4. Вывод справочника иерархически
Шаг 1 (добавляем общий модуль)
Шаг 2 (добавляем в общий модуль код)
&НаСервере
Функция ПолучитьИмяИсточникаДанных(пФорма) Экспорт
лИмя = СтрЗаменить(пФорма.ИмяФормы,»ВнешнийИсточникДанных.Торговля77.Таблица.»,»»);
лИмя = Лев(лИмя,Найти(лИмя,».»)-1);
Возврат лИмя
КонецФункции
&НаСервере
Функция ПолучитьЭлементыРодителя(пСправочник, пРодитель, пР = 0,пМас=0) Экспорт
Запрос = Новый Запрос;
Если пРодитель.Ссылка.Пустая() Тогда
Запрос.Текст =
«ВЫБРАТЬ
| Спр.Ссылка КАК Элемент,
| Спр.Наименование КАК Наименование,
| Спр.Родитель КАК Родитель,
| ВЫБОР
| КОГДА Спр.ЭтоГруппа = 1
| ТОГДА 2
| ИНАЧЕ 1
| КОНЕЦ КАК ЭтоГруппа
|ИЗ
| ВнешнийИсточникДанных.Торговля77.Таблица.»+пСправочник+» КАК Спр
|ГДЕ
| Спр.РодительИД = «» 0 «»
|УПОРЯДОЧИТЬ ПО
| ЭтоГруппа УБЫВ,
| Спр.Наименование»;
Иначе
Запрос.Текст =
«ВЫБРАТЬ
| Спр.Ссылка КАК Элемент,
| Спр.Наименование КАК Наименование,
| Спр.Родитель КАК Родитель,
| ВЫБОР
| КОГДА Спр.ЭтоГруппа = 1
| ТОГДА 2
| ИНАЧЕ 1
| КОНЕЦ КАК ЭтоГруппа
|ИЗ
| ВнешнийИсточникДанных.Торговля77.Таблица.»+пСправочник+» КАК Спр
|ГДЕ
| Спр.Родитель = &Родитель
|
|УПОРЯДОЧИТЬ ПО
| ЭтоГруппа УБЫВ,
| Спр.Наименование»;
Запрос.УстановитьПараметр(«Родитель»,пРодитель);
КонецЕсли;
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
лМассив = Новый Массив;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
лСтруктураЭл = Новый Структура;
лСтруктураЭл.Вставить(«Элемент»,ВыборкаДетальныеЗаписи.Элемент);
лСтруктураЭл.Вставить(«Наименование»,ВыборкаДетальныеЗаписи.Наименование);
лСтруктураЭл.Вставить(«Родитель»,ВыборкаДетальныеЗаписи.Родитель);
лСтруктураЭл.Вставить(«ЭтоГруппа»,ВыборкаДетальныеЗаписи.ЭтоГруппа);
Если пР = 0 Тогда
лМассив.Добавить(лСтруктураЭл);
ИначеЕсли пР = 1 Тогда
пМас.Добавить(лСтруктураЭл);
КонецЕсли;
КонецЦикла;
Если пР = 0 Тогда
Возврат лМассив;
Иначе
Возврат пМас;
КонецЕсли;
КонецФункции
&НаСервере
Процедура ДобавитьДерево(пФорма, пСтруктураОтображенияДерева, пСтруктураДействий) Экспорт
пСправочник = ОбщийМодульСправочники77.ПолучитьИмяИсточникаДанных(пФорма);
лМассивЭлементов = ПолучитьЭлементыРодителя(пСправочник, ВнешниеИсточникиДанных.Торговля77.Таблицы[пСправочник].ПустаяСсылка());
//
ДеревоОбъект = Новый ДеревоЗначений;
ДеревоОбъект.Колонки.Добавить(«Элемент», Новый ОписаниеТипов(«ВнешнийИсточникДанныхТаблицаСсылка.Торговля77.»+пСправочник));
ДеревоОбъект.Колонки.Добавить(«Наименование», Новый ОписаниеТипов(«Строка»));
ДеревоОбъект.Колонки.Добавить(«ЭтоГруппа», Новый ОписаниеТипов(«Число»));
//
Для лчНом=0 По лМассивЭлементов.Количество()-1 Цикл
СтрокаУ1 = ДеревоОбъект.Строки.Добавить();
СтрокаУ1.Элемент = лМассивЭлементов[лчНом].Элемент;
СтрокаУ1.Наименование = лМассивЭлементов[лчНом].Наименование;
СтрокаУ1.ЭтоГруппа = лМассивЭлементов[лчНом].ЭтоГруппа;
Если лМассивЭлементов[лчНом].ЭтоГруппа=2 Тогда
СтрокаУ2 = СтрокаУ1.Строки.Добавить();
СтрокаУ2.Элемент = ВнешниеИсточникиДанных.Торговля77.Таблицы[пСправочник].ПустаяСсылка();
СтрокаУ2.ЭтоГруппа = 0;
КонецЕсли;
КонецЦикла;
// Создание Реквизита формы типа ДанныеФормыДерево
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(«Дерево»,
Новый ОписаниеТипов(«ДеревоЗначений»)));
Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
МассивДобавляемыхРеквизитов.Добавить(
Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, «Дерево»));
КонецЦикла;
пФорма.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
// Преобразование объекта прикладного типа ДеревоЗначений
// в реквизит управляемой формы (данные формы)
пФорма.ЗначениеВРеквизитФормы(ДеревоОбъект, «Дерево»);
// Создание элемента формы типа ТаблицаФормы для отображения дерева
ЭлементДерево = пФорма.Элементы.Добавить(«Дерево», Тип(«ТаблицаФормы»));
Для Каждого лЭлементОтображенияДерево Из пСтруктураОтображенияДерева Цикл
ЭлементДерево[лЭлементОтображенияДерево.Ключ] = лЭлементОтображенияДерево.Значение;
КонецЦикла;
Для Каждого лЭлементДействия Из пСтруктураДействий Цикл
ЭлементДерево.УстановитьДействие(лЭлементДействия.Ключ,лЭлементДействия.Значение);
КонецЦикла;
Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
НовыйЭлемент = пФорма.Элементы.Добавить(Колонка.Имя, Тип(«ПолеФормы»),
ЭлементДерево);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = «Дерево.» + Колонка.Имя;
Если Колонка.Имя = «Элемент» Тогда
НовыйЭлемент.Видимость = Ложь;
КонецЕсли;
Если Колонка.Имя = «ЭтоГруппа» Тогда
НовыйЭлемент.Видимость = Ложь;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Функция ПроверкаВхожденияЭлемента(пКоллекция, пЭлемент) Экспорт
лВозврат = 0;
Для Каждого лЭлемент Из пКоллекция Цикл
Если лЭлемент.Элемент = пЭлемент Тогда
лВозврат = 1;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат лВозврат;
КонецФункции
&НаКлиенте
Функция НайтиПоСтруктуреВМассиве(пМассив, пИмяЭлСтруктуры, пЗнач) Экспорт
лИндекс = Неопределено;
Для лчНом=0 По пМассив.Количество()-1 Цикл
Если пМассив[лчНом][пИмяЭлСтруктуры] = пЗнач Тогда
лИндекс = лчНом;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат лИндекс;
КонецФункции
Шаг 3 (добавляем форму списка для нашего справочника)
ВНИМАНИЕ!!! Форма списка должна быть абсолютно пустой!!! Все отображение будет формировать программно!!!
Шаг 4 (добавляем в модуль формы код)
&НаСервере
Функция ПолучитьИмяДанныхФормы()
лИсточник = ОбщийМодульСправочники77.ПолучитьИмяИсточникаДанных(ЭтаФорма);
Возврат лИсточник;
КонецФункции
&НаСервере
Функция ПолучитьЭлементыРодителя(пРодитель)
лИсточник = ПолучитьИмяДанныхФормы();
Возврат ОбщийМодульСправочники77.ПолучитьЭлементыРодителя(лИсточник, пРодитель);
КонецФункции
&НаСервере
Функция ПолучитьПустуюСсылкуВнешнегоИсточникаДанных(пИмя)
Возврат ВнешниеИсточникиДанных.Торговля77.Таблицы[пИмя].ПустаяСсылка();
КонецФункции
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
СтруктураОтображенияДерева = Новый Структура;
СтруктураОтображенияДерева.Вставить(«ПутьКДанным»,»Дерево»);
СтруктураОтображенияДерева.Вставить(«Отображение»,ОтображениеТаблицы.ИерархическийСписок);
СтруктураОтображенияДерева.Вставить(«КартинкаСтрок»,БиблиотекаКартинок.ГруппаИЭлемент);
СтруктураОтображенияДерева.Вставить(«ПутьКДаннымКартинкиСтроки»,»Дерево.ЭтоГруппа»);
СтруктураДействий = Новый Структура;
СтруктураДействий.Вставить(«ПриСменеТекущегоРодителя»,»ЭлементДеревоПриСменеТекущегоРодителя»);
ОбщийМодульСправочники77.ДобавитьДерево(ЭтаФорма, СтруктураОтображенияДерева, СтруктураДействий);
КонецПроцедуры
&НаКлиенте
Процедура ЭлементДеревоПриСменеТекущегоРодителя(Элемент)
ИДТекущейСтроки = Элементы[«Дерево»].ТекущаяСтрока;
Если ИДТекущейСтроки <> Неопределено Тогда
РеквизитДерево = ЭтаФорма[«Дерево»];
ЭлементКоллекции = РеквизитДерево.НайтиПоИдентификатору(ИДТекущейСтроки);
Родитель = ЭлементКоллекции.ПолучитьРодителя();
Если Родитель <> Неопределено Тогда
ПодчинЭлементы = Родитель.ПолучитьЭлементы();
ПодчинЭлементы.Очистить();
лИсточник = ПолучитьИмяДанныхФормы();
лМассивЭлементов=ПолучитьЭлементыРодителя(Родитель.Элемент);
Для лчНом =0 По лМассивЭлементов.Количество()-1 Цикл
лПотомок = ПодчинЭлементы.Добавить();
лПотомок.Элемент = лМассивЭлементов[лчНом].Элемент;
лПотомок.Наименование = лМассивЭлементов[лчНом].Наименование;
лПотомок.ЭтоГруппа = лМассивЭлементов[лчНом].ЭтоГруппа;
Если лМассивЭлементов[лчНом].ЭтоГруппа = 2 Тогда
ПустойПодчинЭлемент = лПотомок.ПолучитьЭлементы();
лПустойПотомок = ПустойПодчинЭлемент.Добавить();
лПустойПотомок.Элемент = ПолучитьПустуюСсылкуВнешнегоИсточникаДанных(лИсточник);
лПустойПотомок.ЭтоГруппа = 0;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Шаг 5
Привязываем код нашей процедуры ПриСозданииНаСервере к форме
Шаг 6
Для вывода иерархии нам нужен идентификатор родителя ParentID, но мы же его перевели в ссылочный тип, поэтому я просто добавил еще одно поле: РодительИД
Шаг 7
Добавляем в общие картинки (если нет) картинку стандартной библиотеки 1С82 «ГруппаИЭлемент»
Шаг 8
Запускаем режим предприятия и видим в 1С82 справочник из 1С77 красиво, как и положено…
Теперь что бы подключить другой справочник из 1С77 нужно провести минимум действий: добавить таблицу во внешний источник, создать пустую форму, и добавить код для формы… Все! Данную таблицу можно использовать в СКД и формировать отчеты средствами 1С82.
(0) ну так разжевано маленько — отлично усваивается… гуд в целом
Это первая ступенька к настройке доступа на чтение 1С77 из 1С82. Настроен доступ на чтение из 1С82 к 1С77 (справочники, документы и регистры). Воьмерка довольно корректно все отображает. Брал только нужные пользователям реквизиты. Очень помогло при переводе предприятия с 77 на 82. Написаны отчеты сравнения, что есть в новой базе 82 и что есть в старой 77.
Надо бы указать в заголовке, что это только для SQL-баз статья,
а так рассказано все подробно и понятно,
P.s.: еще можно попробовать вместо PrtScr нажимать Alt+PrtScr
Данная статья подходит не только к базе на MS SQL, но и к любой базе, к которой есть драйвера ODBC. Просто взят рабочий пример для 77, которая и лежит в MS SQL. Таким же образом вытаскивал данные с MySQL, PostgreSQL и Access.
И через ComОбъект, и при помощи КД гонять данные, ИМХО, куда менее трудозатратно. Не приходится разбирать 1cv7.dd
Статья неплоха в качестве первичного руководства по внешним источникам данных, но в качестве реального метода импорта данных из 7.7 я бы ее использовать не стал.
Кроме того, когда уже во внешних источниках данных будет поддержка не только SELECT, но и INSERT… А лучше — нативного SQL.
Реальная база с 2006 года по сей момент разрабатывалась только под прямые запросы MS SQL, компонента 1С++. Так что DD разбирать не пришлось, его уже и так выучили наизусть… При помощи COM или OLE пробовали написать отчет, выводящий несоответсвие данных в двух разных базах при номенклатуре около 100 тыс позиций??? В СКД или T-SQL это банальный INNER JOIN.
плюс автору за оригинальность использования средств платформы.
правда, если не засовывать внешний источник в СКД,
то наверное лутше обратиться к «первоисточнику» — к ADO.
Для работы с ADO могу посоветоватьсвои скромные наработки .
Похоже у вас данные считываются только в момент навигации по иерархии. А если режим просмотра дерева переключить в «Список», что будет?! Непорядок будет.
Я не стал дальше расписывать. Данные считываются при навигации, что бы увеличить быстродействие вывода. Т.к. если считывать сразу все дерево, то на больших справочниках большие тормоза (все таки это не курсор, как в штатной системе). Я просто запретил все другие режимы просмотра, не нужны они для внешних источников.
(0) Начиная с п.4 не имеет смысла. Т.к. можно просто указать поле родителя.
(10) awk, Можете пояснить детальнее?
платформа 8.3.8.2088
при подключении к 1с77 для полей «Строка(Х), Х>100» выдает сообщение
ВнешнийИсточникДанных Поле XXX: Для строки фиксированной длины запрещено задавать длину строки более 100 символов
Что делать ?