Главная и подчиненная таблицы в 1С - связывание

16.05.13

Разработка - Механизмы платформы 1С

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

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

Идея:

1. Необходима уникальная скрытая связка в двух таблицах, обеспечивающая простую в обработке синхронизацию полей главной и подчиненной таблиц.

Реализация:

В поисках такой универсальной связки наткнулся на конструкцию вида:

Новый УникальныйИдентификатор;

Как раз его и будем использовать для связывания. В обе табличные части документа добавляем поле с типом УникальныйИдентификатор. После этого необходимо в модуле формы обработать несколько событий, а именно:

ПриНачалеРедактирования - Табличного поля главной таблицы и Табличного поля подчиненной таблицы.

ПередУдалением - Табличного поля главной таблицы для очистки связанных строк подчиненной.

ПриАктивизацииСтроки - для отбора строк подчиненной таблицы.

Вот и все...

А теперь примеры обработчиков, кстати, они универсальны для любых решений.

 

Процедура ГлавнаяТаблицаПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
	
	Данные = ЭлементыФормы.ГлавнаяТаблица.ТекущаяСтрока;
	Если НоваяСтрока Тогда 
		Данные.ИД = Новый УникальныйИдентификатор;
	КонецЕсли;
	
КонецПроцедуры

Процедура ПодчиненнаяТаблицаПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
	
	Данные = ЭлементыФормы.ГлавнаяТаблица.ТекущаяСтрока;
	ТекДанные = ЭлементыФормы.ПодчиненнаяТаблица.ТекущаяСтрока;
	Если НоваяСтрока Тогда
		ТекДанные.ИД = Данные.ИД;
	КонецЕсли;
	
КонецПроцедуры

Процедура ГлавнаяТаблицаПередУдалением(Элемент, Отказ)
	
	Данные = ЭлементыФормы.ГлавнаяТаблица.ТекущаяСтрока;
	Отбор = Новый Структура("ИД",Данные.ИД);
	Масс = ПодчиненнаяТаблица.НайтиСтроки(Отбор);
	Для каждого Строка из Масс Цикл
		ПодчиненнаяТаблица.Удалить(Строка);
	КонецЦикла;
	
КонецПроцедуры

Процедура ГлавнаяТаблицаПриАктивизацииСтроки(Элемент)	
	
	Данные = ЭлементыФормы.ГлавнаяТаблица.ТекущаяСтрока;
	Если Данные = Неопределено Тогда
		Возврат;
	КонецЕсли;	
	ЭлементыФормы.ПодчиненнаяТаблица.ОтборСтрок.ИД.Значение = Данные.ИД;
	ЭлементыФормы.ПодчиненнаяТаблица.ОтборСтрок.ИД.Использование = истина;
	
КонецПроцедуры

И совсем небольшое дополнение - полю ИД устанавливаем Свойство:Индексировать = индексировать.

Поле Табличного Поля можно (и нужно во избежание) сделать недоступным для пользователя.

Жду ваших отзывов и критики :).

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    7454    bayselonarrend    20    

154

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5946    dsdred    16    

80

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    17673    YA_418728146    26    

71

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11225    dsdred    44    

130

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23762    SeiOkami    48    

135

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    18832    human_new    27    

80

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14734    YA_418728146    7    

166
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. kote 537 17.05.13 01:50 Сейчас в теме
Какую практическую задачу Вы решали, где Вам пришлось это применить?
2. BorisMor 310 17.05.13 05:43 Сейчас в теме
(1) kote, автор не открыл Америке. Иногда и правда требуется хранить "сложные данные" и первичный ключ (primary key) - это выход.
Но я предпочитаю использовать для связки осмысленный ключ (ссылку на справочник или значение).
Жаль что на уровне системы не реализована возможность делать ключ уникальным и обращаться по нему к данным из другой таблицы.
4. alex_shkut 63 17.05.13 12:38 Сейчас в теме
(2) Я выполнял поиск решения данной проблемы и не нашел однозначного решения, а мне оно было необходимо. Приведите мне, пожалуйста, хотя-бы пару ссылок с решением данного вопроса. Я вспомнил Access и искал аналогии в 1С. Поскольку я копал Access довольно подробно, а там он используется для синхронизации двух БД - UID был очевидным решением. В 1С на уровне движка можно организовать такое связывание генерируя UID для таблицы со Свойством:Главная и Подчиненная. Для решения многокаскадности достаточно два поля в каждой таблице - MUID SUID, и подчеркиваю только с установленным Свойством.
tp_home@mail.ru; welder; +2 Ответить
5. BorisMor 310 18.05.13 17:25 Сейчас в теме
(4) думаю ссылки не нужны. Про примори кей знают все кто работал с базами. Сочувствую что ваш предшественник оказался таким "уником".
Когда говорил про связь на уровне движка то подразумевал связь между разными таблицами значений.
3. alex_shkut 63 17.05.13 12:31 Сейчас в теме
(1) Спасибо за признание решения. Просто в тех решениях, которые достались мне по наследству это связывание выполнялось по НомеруСтроки!!!. Представьте, что будет, если я отсортирую Главную таблицу?
Пример: ГлавнаяТаблица - поля (которые пашут и сеют - земля)
ПодчиненнаяТаблица - координаты этого Поля с GPS-Агромер.
Итак - к одному "полю" привязано до 500 координат ПО НОМЕРУ СТРОКИ. Нвадеюсь Вы меня поняли...
При использовании моего метода можно совсем забыть про синхронизацию.

Я использовал это решение в связке ВыполненнаяОперация - МногоИспользованыхРесурсов. Такая себе СводкаЗаПериод.
6. KulSer 22.05.13 08:49 Сейчас в теме
Я тоже делал аналогичное связывание по уникальному идентификатору, но, как теперь вижу, несколько перемудрил. Но Ваш код лаконичнее и с первого взгляда понятнее. Спасибо, Александр.
7. Sabfir 22.05.13 09:24 Сейчас в теме
Если сначала добавить строку во вторую таблицу при отсутствии строки в первой таблице, то эти строки не свяжутся.
slawanix; +1 Ответить
8. gaglo 22.05.13 10:15 Сейчас в теме
Так и не понял, почему тип УникальныйИдентификатор показался настолько выгодным. Раз поле для организации связки пришлось добавлять, почему не сделать его числовым? Конечно, не НомерСтроки, а какой-нибудь НомерДляСвязи, уникальный в пределах документа. Код обработчиков практически неизменен, только вместо одной строки "Новый УникальныйИдентификатор" пришлось бы написать пяток операторов, чтоб выяснить максимальный НомерДляСвязи да прибавить к нему 1. (Ну да, и еще УникальныйИдентификатор будет уникальным не только в пределах документа, а по всей базе и окрестностях...)
9. catena 110 22.05.13 11:29 Сейчас в теме
Вообще интересно, почему в таблице значений можно создать вложенную таблицу значений штатными средствами, а в табличных частях это не реализовано.
Maximysis; +1 Ответить
10. ashvik 22.05.13 12:20 Сейчас в теме
Здесь еще нужно предусмотреть возможность копирования строки главной таблицы и, соответственно, копирование подчиненных строк с новым идентификатором.
11. Den_D 54 22.05.13 14:14 Сейчас в теме
Делал так еще в 2007 году, сейчас тоже так делаю, очень удобно. Как сказали в (10) не все ситуации рассмотрены в данном примере кода.
12. zqzq 25 23.05.13 08:44 Сейчас в теме
Конфигурация Управление небольшой фирмой - документ, например, ПриемНаРаботу - используются подчиненные таб. части. Функции для их поддержки в общем модуле УправлениеНебольшойФирмойКлиент. Так что да, автор изобрел велосипед.

Там, кстати, и такое обработано:

	Если ФормаДокумента.Элементы[ФормаДокумента.ИмяТабличнойЧасти].ТекущиеДанные = Неопределено Тогда
		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = НСтр("ru = 'Не выбрана строка основной табличной части!'");
		Сообщение.Сообщить();


Для связи используется числовой инкрементный ключ КлючСвязи (число(5,0)) - занимает меньне иеста чем UUID (вроде бы), но ваше решение более устойчивое (если забыть, например, обработчик после удалеия, строки не переназначатся... хотя всё равно будут висеть невидимые и создавать косяки).
13. alex_shkut 63 24.05.13 11:00 Сейчас в теме
Спасибо за отзывы. Я не старался изобрести велосипед. Эта статья опубликована для тех, кто ищет решение и не находит. А примеры я привел здесь - в обсуждении. И причем это довольно известная компания :). А Уникальный идентификатор ценен тем, что он останется уникальным всегда и везде - как бы вы в последующем не разбрасывали информацию по базе - всегда можно отследить связи между данными.
Я постараюсь дописать базовый код так, чтобы он был минимально достаточным.
По поводу копирования подчиненных строк - это надо рассматривать в каждом конкретном случае, надо или нет. Код закомментированый для копирования я добавлю.
CepeLLlka; +1 Ответить
14. alex_shkut 63 24.05.13 12:02 Сейчас в теме
Если НоваяСтрока Тогда
		Элемент.ТекущаяСтрока.Сотрудник = ЭлементыФормы.РаботникиОрганизации.ТекущаяСтрока.Сотрудник;
	КонецЕсли;


Вот такое-вот решение при приеме на работу в моей конфигурации. Я специально не буду называть разработчика, т.к. это будет совсем неэтично. Мы здесь призваны улучшать то, что есть и создавать правильное новое.
В данном варианте УникальныйИдентификатор - это и есть Ссылка на Сотрудника.
15. alex_shkut 63 10.02.14 15:56 Сейчас в теме
Спасибо за голоса. Перечитал я все посты и понял. Я показал велосипед без колес :). Колеса поставит программист сам - какие ему нужно. Шоссейные (без копирования подчиненных) или горные (с ньюансами). Это достаточный минимум для тех, кто вообще не знает, как это сделать...
16. slawanix 9 12.02.16 17:59 Сейчас в теме
Спасибо автору, плюсанул.
17. ehcore 17.06.16 14:23 Сейчас в теме
Спасибо автору, от себя хочу добавить код, переделанный под управляемые формы (также заблокировано добавление строки в подчиненную при пустой главной):
&НаКлиенте
Процедура ГлавнаяТаблицаПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
	
	Данные = Элементы.ГлавнаяТаблица.ТекущиеДанные;
	Если НоваяСтрока Тогда 
	    Данные.ID = Новый УникальныйИдентификатор;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПодчиненнаяТаблицаПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)

	Данные = Элементы.ГлавнаяТаблица.ТекущиеДанные;
	
	ТекДанные = Элементы.ПодчиненнаяТаблица.ТекущиеДанные;
	Если НоваяСтрока Тогда
	    ТекДанные.ID = Данные.ID;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ГлавнаяТаблицаПередУдалением(Элемент, Отказ)

	Данные = Элементы.ГлавнаяТаблица.ТекущиеДанные;
	Отбор = Новый Структура("ID",Данные.ID);
	Масс = Объект.ПодчиненнаяТаблица.НайтиСтроки(Отбор);
	Для каждого Строка из Масс Цикл
	    Объект.ПодчиненнаяТаблица.Удалить(Строка);
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ГлавнаяТаблицаПриАктивизацииСтроки(Элемент)
	
	Данные = Элементы.ГлавнаяТаблица.ТекущиеДанные;
	Если Данные = Неопределено Тогда
	    Возврат;
	КонецЕсли;    
	Элементы.ПодчиненнаяТаблица.ОтборСтрок = Новый ФиксированнаяСтруктура("ID", Данные.ID);
	
КонецПроцедуры

&НаКлиенте
Процедура ПодчиненнаяТаблицаПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
	
	Данные = Элементы.ГлавнаяТаблица.ТекущиеДанные;
	Если Данные = Неопределено Тогда
	    Отказ = Истина;
	КонецЕсли;   
	
КонецПроцедуры
Показать


Ну и код модуля объекта(очищает подчиненную и присваивает новые ID строкам главной):
Процедура ПриКопировании(ОбъектКопирования)

	ПодчиненнаяТаблица.Очистить();
	Для Каждого Строка Из ГлавнаяТаблица Цикл
		Строка.ID = Новый УникальныйИдентификатор;
	КонецЦикла;	

КонецПроцедуры
Показать
CnupT; Летяга; begemot; klaus38; megatrend; slavyan_arena; MotoBu; berezin84; agdam_m; rafaiil; svilsa; SmArtist; Оберон; +13 Ответить
18. SmArtist 101 16.12.16 07:20 Сейчас в теме
(17), Спасибо, работает. Только нужно в процедуру
ГлавнаяТаблицаПриНачалеРедактирования()

добавить одну строку:
    
Данные = Элементы.ГлавнаяТаблица.ТекущиеДанные;
    Если НоваяСтрока Тогда 
        Данные.ИдентификаторСтроки = Новый УникальныйИдентификатор;
	    Элементы.ПодчиненнаяТаблица.ОтборСтрок = Новый ФиксированнаяСтруктура("ИдентификаторСтроки", Данные.ИдентификаторСтроки);
    КонецЕсли;


потому что событие ПриАктивизацииСтроки по первой таблице срабатывает раньше, чем ПриНачалеРедактирования первой же таблице. В результате накладывается отбор в подчиненной таблице по пустому идентификатору.
Alex_mar; begemot; rafaiil; +3 Ответить
23. berezin84 27.11.20 00:13 Сейчас в теме
(17)
Если Данные = Неопределено Тогда
Возврат;
ИначеЕсли Данные.ID = "" Тогда
Данные.ID = Новый УникальныйИдентификатор;
КонецЕсли;
- в событие ГлавнаяТаблицаПриАктивизацииСтроки.
19. ImHunter 327 16.12.16 07:41 Сейчас в теме
Чем плохи УИДы.
Их нельзя передать в запрос внешней таблицей значений. Списком вроде можно. А вот в ТЗ - увы.
24. egorious 26.11.21 15:41 Сейчас в теме
(19)
я передать в запрос внешней таблицей значений. Списком вроде можно. А вот в ТЗ - увы.


Можно, не вводите в заблуждение.
20. tp_home@mail.ru 04.09.19 15:20 Сейчас в теме
Спасибо! То что надо при моей задаче.
21. bayce 47 03.03.20 22:26 Сейчас в теме
Не всегда работает корректно
Иногда при добавлении остаются строчки. на УФ.
22. eact 13.05.20 12:21 Сейчас в теме
В процедуре "ГлавнаяТаблицаПриАктивизацииСтроки(Элемент)" можно обойтись меньшим куском кода, т.к. в процедуре в переменную "Элемент" нам уже передает система нам все необходимые данные. В других процедурах также можно упростить код.
Этот код работает не хуже первоначального:

Процедура ГлавнаяТаблицаПриАктивизацииСтроки(Элемент)    
    
    ЭлементыФормы.ПодчиненнаяТаблица.ОтборСтрок.ИД.Значение = Элемент.ТекущиеДанные.ИД;
    ЭлементыФормы.ПодчиненнаяТаблица.ОтборСтрок.ИД.Использование = истина;
    
КонецПроцедуры
25. ImHunter 327 26.11.21 15:44 Сейчас в теме
(24) Товарищ, вы видите, в какой год отвечаете?;)
26. egorious 27.12.21 14:42 Сейчас в теме
(25) я вижу тему обсуждения, и вижу что, данный коментарий не отражает действительность. Оберегать хронологию оставляю вам. Удачи. Если, для вас это удар по самолюбию, то дополню, что ваше замечание справедливо до релиза 8.3.12
27. user905682 24.08.22 13:47 Сейчас в теме
Как исправить следующие проблемы?
1) В начале после создании строки в главной таблице, в подчинённой при добавлении строки исчезают и появляются только после перезахода в форму.
2) Нумерация строк в подчинённой начинается неправильно. (во вложении скрин)
Прикрепленные файлы:
Оставьте свое сообщение