gifts2017

Подключение к 1С 7.7 через внешний источник данных, работа со справочниками 7.7 (на примере справочника клиенты)

Опубликовал Дмитрий Соломатин (sdf1979) в раздел Программирование - Практика программирования

Подключение к 1С 77 через внешний источник данных, работа со справочниками 77 (на примере справочника клиенты). Вывод иерархической структуры справочника. В прикрепленном файле пошаговая инструкция с картинками.

Подключение к 1С 77 через внешний источник данных, работа со справочниками 77 (на примере справочника клиенты)

 

  1. Добавление внешнего источника данных

Шаг 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.

 

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Подключение к 1С 77 через внешний источник данных.doc
.doc 2,95Mb
24.01.13
26
.doc 2,95Mb 26 Скачать
ГруппаИЭлемент.bmp
.bmp 1,47Kb
24.01.13
3
.bmp 1,47Kb 3 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Александр Зубцов (iov) 24.01.13 16:15
(0) ну так разжевано маленько - отлично усваивается... гуд в целом
2. Дмитрий Соломатин (sdf1979) 24.01.13 16:24
Это первая ступенька к настройке доступа на чтение 1С77 из 1С82. Настроен доступ на чтение из 1С82 к 1С77 (справочники, документы и регистры). Воьмерка довольно корректно все отображает. Брал только нужные пользователям реквизиты. Очень помогло при переводе предприятия с 77 на 82. Написаны отчеты сравнения, что есть в новой базе 82 и что есть в старой 77.
3. krein (krein) 25.01.13 08:07
Надо бы указать в заголовке, что это только для SQL-баз статья,
а так рассказано все подробно и понятно,
P.s.: еще можно попробовать вместо PrtScr нажимать Alt+PrtScr
4. Дмитрий Соломатин (sdf1979) 28.01.13 10:39
Данная статья подходит не только к базе на MS SQL, но и к любой базе, к которой есть драйвера ODBC. Просто взят рабочий пример для 77, которая и лежит в MS SQL. Таким же образом вытаскивал данные с MySQL, PostgreSQL и Access.
5. Антон Стеклов (asved.ru) 30.01.13 11:52
И через ComОбъект, и при помощи КД гонять данные, ИМХО, куда менее трудозатратно. Не приходится разбирать 1cv7.dd

Статья неплоха в качестве первичного руководства по внешним источникам данных, но в качестве реального метода импорта данных из 7.7 я бы ее использовать не стал.

Кроме того, когда уже во внешних источниках данных будет поддержка не только SELECT, но и INSERT... А лучше - нативного SQL.
6. Дмитрий Соломатин (sdf1979) 30.01.13 12:04
Реальная база с 2006 года по сей момент разрабатывалась только под прямые запросы MS SQL, компонента 1С++. Так что DD разбирать не пришлось, его уже и так выучили наизусть... При помощи COM или OLE пробовали написать отчет, выводящий несоответсвие данных в двух разных базах при номенклатуре около 100 тыс позиций??? В СКД или T-SQL это банальный INNER JOIN.
7. Юрий Осипов (yuraos) 31.01.13 07:01
плюс автору за оригинальность использования средств платформы.
правда, если не засовывать внешний источник в СКД,
то наверное лутше обратиться к "первоисточнику" - к ADO.

Для работы с ADO могу посоветовать свои скромные наработки.
8. Денис Новосёлов (binex) 22.12.13 18:46
Похоже у вас данные считываются только в момент навигации по иерархии. А если режим просмотра дерева переключить в "Список", что будет?! Непорядок будет.
9. Дмитрий Соломатин (sdf1979) 23.12.13 09:59
Я не стал дальше расписывать. Данные считываются при навигации, что бы увеличить быстродействие вывода. Т.к. если считывать сразу все дерево, то на больших справочниках большие тормоза (все таки это не курсор, как в штатной системе). Я просто запретил все другие режимы просмотра, не нужны они для внешних источников.
10. Василий Казьмин (awk) 09.01.14 15:44
(0) Начиная с п.4 не имеет смысла. Т.к. можно просто указать поле родителя.
11. andrey P (andrey314) 19.02.14 20:24
(10) awk, Можете пояснить детальнее?
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа