Что такое ключ связи в 1с
1С 8.1. УТ. В табличной части документа Заказ покупателя, есть реквизит Ключ строки. Для чего он, и как его пользовать? Спасибо.
(0) возможно, для связи с другими табличными частями
(0) Для связи с ТЧ СоставНабора. Если используешь комплекты — пригодится 🙂
(0) +(1) и вроде бы для группировки товаров-наборов
Вне зависимости от перемещения строки по таблице ее Ключ не меняется, что позволяет четко определить связь с другими таблицами (подчиненными, например)
Значит при программном вводе Реализации ТиУ на основании Заказ покупателя, ключ строки роли не играет. Так получается?
Главная и подчиненная таблицы в 1С — связывание
Наверняка многие сталкивались с вопросом о связывании двух- и более таблиц на формах 1С по принципу главная-подчиненная. Один из возможных вариантов решения я приведу в этой статье. Некоторые решения я уже встречал, но они либо ограничивают возможности таблиц (невозможность сортировки, изменения номера строки и перестановки строк местами) либо требовали дополнительного кода по обработке различных изменений в связанной информации. Предлагаю более разумное и довольно простое решение.
Наверняка многие сталкивались с вопросом о связывании двух- и более таблиц на формах 1С по принципу главная-подчиненная. Один из возможных вариантов решения я приведу в этой статье. Некоторые решения я уже встречал, но они либо ограничивают возможности таблиц (невозможность сортировки, изменения номера строки и перестановки строк местами) либо требовали дополнительного кода по обработке различных изменений в связанной информации. Предлагаю более разумное и довольно простое решение. Идея: 1. Необходима уникальная скрытая связка в двух таблицах, обеспечивающая простую в обработке синхронизацию полей главной и подчиненной таблиц. Реализация: В поисках такой универсальной связки наткнулся на конструкцию вида:
Новый УникальныйИдентификатор;
Как раз его и будем использовать для связывания. В обе табличные части документа добавляем поле с типом УникальныйИдентификатор. После этого необходимо в модуле формы обработать несколько событий, а именно: ПриНачалеРедактирования — Табличного поля главной таблицы и Табличного поля подчиненной таблицы. ПередУдалением — Табличного поля главной таблицы для очистки связанных строк подчиненной. ПриАктивизацииСтроки — для отбора строк подчиненной таблицы. Вот и все. А теперь примеры обработчиков, кстати, они универсальны для любых решений.
Процедура ГлавнаяТаблицаПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование) Данные = ЭлементыФормы.ГлавнаяТаблица.ТекущаяСтрока; Если НоваяСтрока Тогда Данные.ИД = Новый УникальныйИдентификатор; КонецЕсли; КонецПроцедуры Процедура ПодчиненнаяТаблицаПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование) Данные = ЭлементыФормы.ГлавнаяТаблица.ТекущаяСтрока; ТекДанные = ЭлементыФормы.ПодчиненнаяТаблица.ТекущаяСтрока; Если НоваяСтрока Тогда ТекДанные.ИД = Данные.ИД; КонецЕсли; КонецПроцедуры Процедура ГлавнаяТаблицаПередУдалением(Элемент, Отказ) Данные = ЭлементыФормы.ГлавнаяТаблица.ТекущаяСтрока; Отбор = Новый Структура("ИД",Данные.ИД); Масс = ПодчиненнаяТаблица.НайтиСтроки(Отбор); Для каждого Строка из Масс Цикл ПодчиненнаяТаблица.Удалить(Строка); КонецЦикла; КонецПроцедуры Процедура ГлавнаяТаблицаПриАктивизацииСтроки(Элемент) Данные = ЭлементыФормы.ГлавнаяТаблица.ТекущаяСтрока; Если Данные = Неопределено Тогда Возврат; КонецЕсли; ЭлементыФормы.ПодчиненнаяТаблица.ОтборСтрок.ИД.Значение = Данные.ИД; ЭлементыФормы.ПодчиненнаяТаблица.ОтборСтрок.ИД.Использование = истина; КонецПроцедуры
И совсем небольшое дополнение — полю ИД устанавливаем Свойство:Индексировать = индексировать. Поле Табличного Поля можно (и нужно во избежание) сделать недоступным для пользователя. Жду ваших отзывов и критики :).
Связанные табличные части (управляемые формы)
У нас есть 2 связанные табличные части, и нам надо, чтобы по текущей строке в одной из них мы видели только определенные строки во второй. Были бы у нас динамические списки, мы бы взяли событие «При активизации строки» и стандартный механизм отборов СКД, которая лежит в основе списка. Но вот с табличными частями так не получится. Тут нам надо будет написать несколько строк кода и использовать «ОтборСтрок», доступный для таблицы формы. Тестировалось на платформе 8.3.13.1644, будет работать и на более ранних версиях платформы.
Скачать файлы
Про «ОтборСтрок» я уже писал в недалеком прошлом поэтому не буду повторяться. Что это и для чего это используется можно изучить в статье Отборы (поиск) в табличной части либо таблице значений (управляемые формы)
Для демонстрации механизма я снова подготовил небольшую конфигурацию, которую можно скачать.
Конфигурация состоит из двух справочников: «Контрагенты» и «Товары» и одного документа «Поступление товаров». Данный документ имеет 2 соответствующие табличные части и предназначен для получения товаров от разных клиентов в одном документе.
Визуально форма выглядит так:
Мы хотим сделать так, чтобы клиенту было удобно и он выбирая клиента видел только те товары, которые приходят от него.
В качестве ключа связи мы будем использовать само значение контрагента. При этом можно в качестве ключа связи использовать произвольные ключи, уникальные в пределах документа или любые ссылочные элементы, например договора контрагентов — все зависит только от вашей необходимости.
Для нашей левой табличной части «Контрагенты» нам надо добавить следующие обработчики событий:
Нам надо при активизации строки показывать только товары, принадлежащие выбранному контрагенту (События «При активизации строки» и «При окончании редактирования») и так же отработать ситуацию удаления контрагента — нам надо удалить все товары со второй табличной части.
&НаКлиенте Процедура КонтрагентыПриАктивизацииСтроки(Элемент) ТекДанные = Элемент.ТекущиеДанные; УстановитьОтборПоКлючу(ТекДанные,Элементы.Товары,НаименованиеКлючаСвязи); КонецПроцедуры &НаКлиенте Процедура КонтрагентыПередУдалением(Элемент, Отказ) ОбщаяПроцедураУдалитьСтроки(Элемент.ТекущиеДанные,Объект.Товары,НаименованиеКлючаСвязи); КонецПроцедуры &НаКлиенте Процедура КонтрагентыПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования) ТекДанные = Элемент.ТекущиеДанные; ТекНаименованиеКлюча = НаименованиеКлючаСвязи; Если ТекДанные[ТекНаименованиеКлюча] <> ТекДанные[ТекНаименованиеКлюча + "Начальный"] Тогда ПерезаполнитьЗначениеКлюча(ТекДанные[ТекНаименованиеКлюча+"Начальный"],ТекДанные[ТекНаименованиеКлюча],"Товары",ТекНаименованиеКлюча); ТекДанные[ТекНаименованиеКлюча + "Начальный"] = ТекДанные[ТекНаименованиеКлюча]; КонецЕсли; УстановитьОтборПоКлючу(ТекДанные,Элементы.Товары,ТекНаименованиеКлюча); КонецПроцедуры
Сами процедуры обработки:
&НаКлиенте Процедура УстановитьОтборПоКлючу(ТекДанные,ТекЭлем,НаименованиеКлюча) Если ТекДанные = Неопределено Тогда Возврат; КонецЕсли; // Создаем структуру отбора Отбор = Новый Структура; Отбор.Вставить(НаименованиеКлюча, ТекДанные[НаименованиеКлюча]); // Задаем фиксированную структуру отбора для таблицы формы ТекЭлем.ОтборСтрок = Новый ФиксированнаяСтруктура(Отбор); КонецПроцедуры &НаКлиенте Процедура ОбщаяПроцедураУдалитьСтроки(ТекДанные,ТекЭлем,НаименованиеКлюча) Если ТекДанные <> Неопределено Тогда МассивСтрок = ТекЭлем.НайтиСтроки(Новый Структура (НаименованиеКлюча,ТекДанные[НаименованиеКлюча])); Для Каждого СтрМассива ИЗ МассивСтрок Цикл ТекЭлем.Удалить(СтрМассива); КонецЦикла; КонецЕсли; КонецПроцедуры &НаСервере Процедура ПерезаполнитьЗначениеКлюча (ЗначениеКлючаНачальный,ЗначениеКлюча,НаименованиеТабЧасти,НаименованиеКлюча) Если ЗначениеЗаполнено(ЗначениеКлючаНачальный) Тогда ТекЭлем = Объект[НаименованиеТабЧасти]; МассивСтрок = ТекЭлем.НайтиСтроки(Новый Структура (НаименованиеКлюча,ЗначениеКлючаНачальный)); Для Каждого СтрМассива ИЗ МассивСтрок Цикл СтрМассива[НаименованиеКлюча] = ЗначениеКлюча; КонецЦикла; КонецЕсли; КонецПроцедуры
Для правой табличной части «Товары» нам также надо обработать несколько событий:
Мы должны отклонить выбор номенклатуры если у нас нет или не выбран контрагент и автоматически заполнять значение ключа связи — в нашем случае это ссылка на контрагента. Сами процедуры:
&НаКлиенте Процедура ТоварыПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр) Если Элементы.Контрагенты.ТекущиеДанные = Неопределено Тогда Отказ = Истина; КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ТоварыПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование) Если НоваяСтрока И НЕ Копирование Тогда Элемент.ТекущиеДанные[НаименованиеКлючаСвязи] = Элементы.Контрагенты.ТекущиеДанные[НаименованиеКлючаСвязи]; КонецЕсли; КонецПроцедуры
Ну и в основном для вопросов отладки нам надо посмотреть все товары всех клиентов, для этого добавляем команду по очистке отборов и размещаем ее в интерфейсе с ограничением по правам (если требуется). Процедура простейшая:
&НаКлиенте Процедура ОчиститьОтбор(Команда) СнятьОтборСЭлементов(Элементы.Товары); КонецПроцедуры
Для того, чтобы учесть возможность смены самого контрагента, мы добавили в форме реквизит табличной части :
Сделали его заполнение при открытии формы и обрабатываем его изменение в коде:
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) //Определим ключ связи НаименованиеКлючаСвязи = "Контрагент"; ДозаполнитьТабЧасть(); КонецПроцедуры &НаСервере Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи) ДозаполнитьТабЧасть(); КонецПроцедуры &НаСервере Процедура ДозаполнитьТабЧасть () Для Каждого СтрТаб ИЗ Объект.Контрагенты Цикл СтрТаб[НаименованиеКлючаСвязи+"Начальный"] = СтрТаб[НаименованиеКлючаСвязи]; КонецЦикла; КонецПроцедуры
Для большей универсальности стал использовать реквизит формы «НаименованиеКлючаСвязи», который устанавливаю 1 раз и использую потом везде.
При этом хочу обратить ваше внимание вопрос повторности контрагентов остается открытым — т.е. при выборе слева одного контрагента 2 раза система не сможет различить номенклатуру по строкам. Вам либо надо контролировать, чтобы информация слева была уникальная и/или неизменной.
Для презентации того, как можно учесть и данный случай, я добавил в конфигурацию еще один документ «ПродажаТовара», в котором в качестве ключа связи испльзуется уникальный индекс — простое число, которое уникально для каждой строки слева и привязка идет непосредственно к нему:
Механизм реализации такой абсолютно такой же.
1С:Система лицензирования и защиты конфигураций (СЛК)
«1С:Система лицензирования и защиты конфигураций» является простым в использовании, но эффективным инструментарием для разработчиков прикладных решений. При этом необходимость знаний других языков программирования помимо «1С:Предприятия 8» отсутствует. «1С:СЛК» позволяет быстро приступить к ее использованию при разработке конечного продукта и сосредоточиться на решении следующих задач:
- надежно защитить оригинальный авторский код конфигурации, представляющий «ноу-хау» разработчика от несанкционированного использования и анализа;
- обеспечить технически лицензирование конечного программного продукта; контролировать количество рабочих мест, в соответствии со значением в ключе лицензий при любом режиме работы «1С:Предприятия» 8.2 и 8.3 (толстый, тонкий и web клиенты);
- гибко изменять возможности и управлять работой прикладного решения в зависимости от параметров ключа: ограничивать работу конфигурации по времени, разделять функционал на отдельно активируемые ключом части.
«1С:СЛК» предлагает к использованию разнообразные так называемые «ключи защиты» конфигурации.
Ключи защиты – компонент системы, предназначенный для доступа к защищенным объектам и контроля количества лицензий на основе указанного в ключе значения.
Для каждой защищаемой конфигурации создается своя, уникальная, серия ключей, что делает ключи от одной конфигурации несовместимыми с ключами от других конфигураций. В рамках серии ключи различаются типом.Ключ защиты может быть следующих типов:
- Основной — предназначен для использования в «основных поставках» продукта.
- Дополнительный — предназначен для увеличения количества рабочих мест, используется в «дополнительных лицензиях» к «основной поставке» продукта. Особенностью дополнительных ключей является то, что они не работают без основного ключа и обязательно должны быть подключены к тому же компьютеру, что и основной.
Каждый ключ содержит заданное количество лицензий, которое определяет максимально возможное число одновременно занимаемых лицензий.
Кроме того, ключ защиты может быть аппаратным или программным.
Аппаратный ключ защиты представляет собой ключ, подключаемый в USB разъем компьютера.
В качестве программного ключа используется код активации, представляющий из себя число-буквенный код, предназначенный для получения программной лицензии. Програмная лицензия хранится на жестком диске компьютера.
Также предлагается к использованию объединенный вариант аппаратно-программного ключа защиты. Смысл объединенного варианта заключается в том, что пользователь может на месте выбрать требуемый вид ключа защиты в зависимости от потребностей: будь то необходимость периодического переноса рабочего места (предпочтителен аппаратный ключ), будь то «облачное» расположение рабочей базы (необходим программный ключ).