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

16.05.13

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

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

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

Идея:

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

Реализация:

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

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

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

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

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

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

Вот и все...

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

 

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

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

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

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

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

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

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

См. также

Сервисы интеграции без Шины и интеграции

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

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

13.03.2024    2560    dsdred    16    

59

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    5893    dsdred    53    

83

Как готовить и есть массивы

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

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

24.01.2024    5845    YA_418728146    25    

68

Планы обмена VS История данных

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

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

11.12.2023    6963    dsdred    36    

113

1С-ная магия

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

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

06.10.2023    19051    SeiOkami    46    

118

Дефрагментация и реиндексация после перехода на платформу 8.3.22

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

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

14.09.2023    12761    human_new    27    

76

Валидация JSON через XDTO (включая массивы)

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

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

28.08.2023    9382    YA_418728146    6    

143

Внешние компоненты Native API на языке Rust - Просто!

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

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6524    sebekerga    54    

95
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. kote 536 17.05.13 01:50 Сейчас в теме
Какую практическую задачу Вы решали, где Вам пришлось это применить?
+
2. BorisMor 310 17.05.13 05:43 Сейчас в теме
(1) kote, автор не открыл Америке. Иногда и правда требуется хранить "сложные данные" и первичный ключ (primary key) - это выход.
Но я предпочитаю использовать для связки осмысленный ключ (ссылку на справочник или значение).
Жаль что на уровне системы не реализована возможность делать ключ уникальным и обращаться по нему к данным из другой таблицы.
+
4. alex_shkut 62 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 62 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 Сейчас в теме
Здесь еще нужно предусмотреть возможность копирования строки главной таблицы и, соответственно, копирование подчиненных строк с новым идентификатором.
Den_D; +1
11. Den_D 54 22.05.13 14:14 Сейчас в теме
Делал так еще в 2007 году, сейчас тоже так делаю, очень удобно. Как сказали в (10) не все ситуации рассмотрены в данном примере кода.
+
12. zqzq 23 23.05.13 08:44 Сейчас в теме
Конфигурация Управление небольшой фирмой - документ, например, ПриемНаРаботу - используются подчиненные таб. части. Функции для их поддержки в общем модуле УправлениеНебольшойФирмойКлиент. Так что да, автор изобрел велосипед.

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

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


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


Вот такое-вот решение при приеме на работу в моей конфигурации. Я специально не буду называть разработчика, т.к. это будет совсем неэтично. Мы здесь призваны улучшать то, что есть и создавать правильное новое.
В данном варианте УникальныйИдентификатор - это и есть Ссылка на Сотрудника.
+
15. alex_shkut 62 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 = Новый УникальныйИдентификатор;
	КонецЦикла;	

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

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


потому что событие ПриАктивизацииСтроки по первой таблице срабатывает раньше, чем ПриНачалеРедактирования первой же таблице. В результате накладывается отбор в подчиненной таблице по пустому идентификатору.
Alex_mar; begemot; rafaiil; +3
23. berezin84 27.11.20 00:13 Сейчас в теме
(17)
Если Данные = Неопределено Тогда
Возврат;
ИначеЕсли Данные.ID = "" Тогда
Данные.ID = Новый УникальныйИдентификатор;
КонецЕсли;
- в событие ГлавнаяТаблицаПриАктивизацииСтроки.
+
19. ImHunter 315 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 45 03.03.20 22:26 Сейчас в теме
Не всегда работает корректно
Иногда при добавлении остаются строчки. на УФ.
+
22. eact 13.05.20 12:21 Сейчас в теме
В процедуре "ГлавнаяТаблицаПриАктивизацииСтроки(Элемент)" можно обойтись меньшим куском кода, т.к. в процедуре в переменную "Элемент" нам уже передает система нам все необходимые данные. В других процедурах также можно упростить код.
Этот код работает не хуже первоначального:

Процедура ГлавнаяТаблицаПриАктивизацииСтроки(Элемент)    
    
    ЭлементыФормы.ПодчиненнаяТаблица.ОтборСтрок.ИД.Значение = Элемент.ТекущиеДанные.ИД;
    ЭлементыФормы.ПодчиненнаяТаблица.ОтборСтрок.ИД.Использование = истина;
    
КонецПроцедуры
klaus38; +1
25. ImHunter 315 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) Нумерация строк в подчинённой начинается неправильно. (во вложении скрин)
Прикрепленные файлы:
+
Оставьте свое сообщение