Всем доброго времени суток. Возник такой вопрос: При работе с табличной частью справочника, значение записывается в регистр сведений, как многие знают, в одном регистре не могут хранится значения с одинаковыми измерениями а в справочнике таких ограничений нет, поэтому если в табличной части справочника вводить одинаковые значения то в регистре записывается последнее. Как можно либо запретить ввод одинаковых значений (по измерениям) или автоматически удалять старые строчки табличной части справочника - приводить таблицу к значениям регистра?
---
&НаКлиенте
Процедура ТаблицаРесурсыИзделияПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
Если НЕ ОтменаРедактирования И ТаблицаРесурсыИзделия.НайтиСтроки(Новый структура("РесурсИзделия", Элемент.ТекущиеДанные.РесурсИзделия)).Количество() > 1 Тогда
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
как-то так, если проверять только на "ресурсизделия".
Плюс эту процедуру надо назначить как обработчик для таб.части
---
```1c
    &НаКлиенте
    Процедура Реквизит1ПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
    Если НЕ ОтменаРедактирования И Реквизит1.НайтиСтроки(Новый структура("реквизит1", Элемент.ТекущиеДанные.Реквизит1)).Количество() > 1 Тогда
    Отказ = Истина;
    Сообщить("Ычо! Дубль жы!!!");
    КонецЕсли;
    КонецПроцедуры
```

Реквизит1 - таблица значений
В ней Реквизит1 - контролируемый реквизит.
---
Тогда тебе надо перез записью проверить двойников в ТЗ запросо, удалить их из ТЗ и уже после этого писать в РС, что то типо такого

```1c
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ
    | Товары.Код
    |ИЗ
    | НовыйДокПоступление.Товары КАК Товары
    |
    |СГРУППИРОВАТЬ ПО
    | Товары.Код";
    Результат = Запрос.Выполнить();
    ТЗ = Новый ТаблицаЗначений;
    Результат.Выгрузить(ТЗ);

    ТЗ.ВыбратьСтроки();
    Пока ТЗ.ПолучитьСтроку()=1 Цикл
    ВыбратьСтроки();
    Пока ПолучитьСтроку()=1 Цикл
    Если (ТЗ.Код = Код)
    И (ТЗ.НомерСтроки<>НомерСтроки) Тогда
    Сообщить ("В строке №"+НомерСтроки+" имеется одинаковый код");
    КонецЕсли;
    КонецЦикла;
    КонецЦикла;
```
---
Пообще РС не позвонил сделать записи с одинаковыми значениями, по хорошему Вам надо бы выяснить, справочник является ли регистратором для этого РС?
---
При добавлении значения в табличную часть справочника, при записи он добавляет в регистр это значение.
---
а сам элемент правочника в это РС указывается?
---
Лучше запись в РС сделать после записи элемента справочника. Так будет правильнее. А пользователь в это время пусть что хочет то и лепит с табличную часть.
---
Так и сделано, но проблема в том, что в табличной части справочника он может вводить сколько угодно одинаковых значений а в РС будет отображаться только последнее и тут нужно либо как то запретить пользователю создавать одинаковые значения либо как то чистить табличную часть от того что не отображено в справочнике.
(4) Да, он указывается в измерениях

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

&НаСервереБезКонтекста
Функция ПолучитьДанныеТаблицы_РесурсыИзделияНаСервере(Ссылка)

 Запрос = Новый Запрос;
 Запрос.УстановитьПараметр("Ссылка", Ссылка);
 Запрос.Текст =
 "ВЫБРАТЬ
 | Ресурсы.Изделие КАК Изделие,
 | Ресурсы.РесурсИзделия КАК РесурсИзделия,
 | Ресурсы.СрокСлужбы КАК СрокСлужбы,
 | Ресурсы.СрокХранения КАК СрокХранения,
 | Ресурсы.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
 | Ресурсы.УстановленныйРесурс КАК УстановленныйРесурс,
 | Ресурсы.УсловияХранения КАК УсловияХранения,
 | Ресурсы.ПризнакОсновногоРесурса КАК ПризнакОсновногоРесурса,
 | Ресурсы.Примечание КАК Примечание
 |ИЗ
 | РегистрСведений.Ресурсы КАК Ресурсы
 |ГДЕ
 | Ресурсы.Изделие.Ссылка = &Ссылка"
 ;

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

 Возврат ДанныеТаблицы;

КонецФункции

#КонецОбласти
---
Может тогда перед сохранением элемента справочника просто проверять таблицу на дубли, и удалять их сразу?
---
Тоже как вариант, но получается что нужно как то проверить на схожесть значения 2 столбцов. Вопрос: как это сделать?
---
Имею ввиду проверить два столбца в ТЧ Справочника - значения которых являются измерениями регистра
---
пример столбцов можно?
---
Ресурс Изделия и наименование являются для РС измерениями, вот их как раз вместе повторять нельзя.
---
с РС все понятно из запроса. Я не понял про сравнение двух столбцов в ТЧ, их бы увидеть. чего там вносят.
---
Ресурс изделия это ссылка на Справочник где идет выбор значения , а наименование это ссылка на справочник в котором создаем эту запись (если не выбирать то по умолчанию в регистр падает название справочника)
---
тобишь в одной ТЧ дважды могут заколотить напримерно Сигареты и наименовае Винстон?
---
Да, в тч могут хоть двадцать раз забить данные с этими одинаковыми столбцами, а в регистр запишет только последний. Вот это и нужно поправить.
---
```1c
    &НаКлиенте
    Процедура Реквизит1ПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
    Если НЕ ОтменаРедактирования И Реквизит1.НайтиСтроки(Новый структура("реквизит1", Элемент.ТекущиеДанные.Реквизит1)).Количество() > 1 Тогда
    Отказ = Истина;
    Сообщить("Ычо! Дубль жы!!!");
    КонецЕсли;
    КонецПроцедуры
```

Реквизит1 - таблица значений
В ней Реквизит1 - контролируемый реквизит.
---
Не понимает реквизиты...
---
И там мне получается нужно контролировать 2 реквизита. Но за помощь спасибо, попробую поправить код под себя.
---
Естественно, как он поймет что в ТЧ 2 строки с одинаковым реквизитом, если ты обращаешься к текущим данным элемента)))
---
Я подумал исправить положение добавив в Процедуру ПриСозданииНаСервере следующий код:

 //ОбновлениеТаблицыРесурсов();

Объект.ТаблицаРесурсыИзделия.Очистить();
  ВыборкаЗаписейРегистра = РегистрыСведений.Ресурсы.Выбрать();
Пока ВыборкаЗаписейРегистра.Следующий() Цикл
    НоваяСтрокаТабличнойЧасти = Объект.Ссылка.Добавить();
    НоваяСтрокаТабличнойЧасти.РесурсИзделия = ВыборкаЗаписейРегистра.РесурсИзделия;//ИмяИзмерения - это то поле, в котором у вас содержатся значения а, б, в...
 КонецЦикла;

Но ему не нравится "Объект.Ссылка.Добавить();"
---
Хорошая новость, немного поправил код (свои же тупые ошибки) и данные с регистра начали падать (правда пустые)
---
Правильно что не нравится, не в ссылку надо добавлять а в Объект.ТвояТЧ.Добавить()
---
Теперь он у меня все данные из регистра подгружает в каждый справочник

 Объект.ТаблицаРесурсыИзделия.Очистить();
  ВыборкаЗаписейРегистра = РегистрыСведений.Ресурсы.Выбрать();
 Пока ВыборкаЗаписейРегистра.Следующий() Цикл
    НоваяСтрокаТабличнойЧасти = Объект.ТаблицаРесурсыИзделия.Добавить();
    НоваяСтрокаТабличнойЧасти.РесурсИзделия = ВыборкаЗаписейРегистра.Изделие;
 КонецЦикла;
---
ВыборкаЗаписейРегистра = РегистрыСведений.Ресурсы.Выбрать();
поменять на
```1c
    ВыборкаЗаписейРегистра = РегистрыСведений.Ресурсы.Выбрать(,,Новый Структура("Изделие, РесурсИзделия", Ссылка, РесурсИзделия));
```

Заменить/добавить на нужные измерения и подогнать соответствующие(по типу) реквизиты для отбора
---
("Изделие, РесурсИзделия", Ссылка, РесурсИзделия));
Как я понял "Изделие, РесурсИзделия" это измерения? а Ссылка,РесурсИзделия это реквизиты ТЧ в справочнике?
---
да
---
Спасибо, а в каком виде вводить ссылку и ресурс изделия? Он не хочет читать в этом виде.
---
видимо Объект.Ссылка, Объект.РесурсИзделия.
вообще для этого надо узнать ПутьКДанным этого реквизита.
На скринах можно посмотреть разницу: для одного случая - это реквизит формы, он без "Объект." идёт, а в другом случае это реквизит регистра, и сам реквизит переименован с "объект" в "НастройкиУчетаУСН"
---
Всеравно, если указываю тоже самое что и прописано в пути то не может найти...
---
т.к. это реквизит табличной части, то там надо и номер строки указывать, из какой брать нужное значение.
Можно, конечно, написать так :
```1c
    Объект.ТаблицаРесурсыИзделия[0].РесурсИзделия
```
 но так, он возьмёт значение из первой строки (и то если она будет отсутствовать то выйдет ошибка).
зы: Что-то мы отошли от начальной темы. Вроде еще вчера обсуждали, что можно обойтись без табличной части, а создать реквизит с типом РегистрСведенийНаборЗаписей и работать с ним
---
Просто у меня вчера через табличную часть все идеально встало)
---
Если рассматривать задачу чисто в образовательных целях, то для того, что бы избежать дублей в табличной части, надо добавить ей обработчик - ПриОкончанииРедактирования и там прописать условие на поиск такой же строки в т.ч. (выше вроде приводили код такой)
---
Если вы про этот код:

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

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

Да, я так же подумал, но тогда выдает ошибку о неизвестной колонке(
---
```1c
    Объект.ТаблицаРесурсыИзделия.найтиСтроки(....
```

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

{Справочник.ЭФО.Форма.ФормаЭлемента.Форма(75)}: Слишком много фактических параметров
  ВыборкаЗаписейРегистра = РегистрыСведений.Ресурсы.Выбрать(,,Новый Структура(" Изделие, РесурсИзделия", Объект.Ссылка,Объект.ТаблицаРесурсыИзделия));
---
Просто при проверке он выдает ошибку

{Справочник.ЭФО.Форма.ФормаЭлемента.Форма(75,126)}: Переменная не определена (РесурсИзделия)
  ВыборкаЗаписейРегистра = РегистрыСведений.Ресурсы.Выбрать(,,Новый Структура(" Изделие, РесурсИзделия", НаименованиеИзделия,<<?>>РесурсИзделия)); (Проверка: Сервер)
---
Можно же просто, перед записью элемента добавить Процедуру ПроверимТЧ, там тупо можно запросом тем же проверяем всю ТЧ на наличие двойных записей, пинаем результат в Массив и циклом убивает Строки из Массива в ТЧ.
---
Или просто Просто пере записью ТЧ.Свернуть("Реквизит1, Реквизит2");
---
И уже в регистр тупо выплевывать нужные данные)
---
Только мне не понятно как это сделать.
---
ТЧ это реквизит или элемент формы?
---
Элемент формы (насколько я понимаю)
---
Можно попробовать так:

 Запрос = Новый Запрос;
 Запрос.УстановитьПараметр("Ссылка", Ссылка);
 Запрос.Текст =
 "ВЫБРАТЬ
 | Ресурсы.Изделие КАК Изделие,
 | Ресурсы.РесурсИзделия КАК РесурсИзделия,
 | Ресурсы.СрокСлужбы КАК СрокСлужбы,
 | Ресурсы.СрокХранения КАК СрокХранения,
 | Ресурсы.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
 | Ресурсы.УстановленныйРесурс КАК УстановленныйРесурс,
 | Ресурсы.УсловияХранения КАК УсловияХранения,
 | Ресурсы.ПризнакОсновногоРесурса КАК ПризнакОсновногоРесурса,
 | Ресурсы.Примечание КАК Примечание
 |ИЗ
 | РегистрСведений.Ресурсы КАК Ресурсы
 |ГДЕ
 | Ресурсы.Изделие.Ссылка = &Ссылка"
 ;

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

 Возврат ДанныеТаблицы;

Но это через функцию...
---
Почему бы не сделать в справочнике отображение табличной части как набор записей регистра? И сразу в этот регистр писать при редактировании ТЧ
---
Отказался от этой мысли, так как не очень хорошо давать пользователю возможность редактировать регистр на прямую, проще чтобы он спокойно делал все в справочнике и после обработки данных они попадали в РС.
---
Так еще раз, что то я запутался, Есть ТЗ которая является реквизитом, это уже хорошо, в этой ТЗ забиваются данные, которые могут быть задублинованными, и эти дубли попадают в твой РС, все правильно?
---
Да, данные из ТЧ Справочника попадают в РС
---
Тогда тебе надо перез записью проверить двойников в ТЗ запросо, удалить их из ТЗ и уже после этого писать в РС, что то типо такого

```1c
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ
    | Товары.Код
    |ИЗ
    | НовыйДокПоступление.Товары КАК Товары
    |
    |СГРУППИРОВАТЬ ПО
    | Товары.Код";
    Результат = Запрос.Выполнить();
    ТЗ = Новый ТаблицаЗначений;
    Результат.Выгрузить(ТЗ);

    ТЗ.ВыбратьСтроки();
    Пока ТЗ.ПолучитьСтроку()=1 Цикл
    ВыбратьСтроки();
    Пока ПолучитьСтроку()=1 Цикл
    Если (ТЗ.Код = Код)
    И (ТЗ.НомерСтроки<>НомерСтроки) Тогда
    Сообщить ("В строке №"+НомерСтроки+" имеется одинаковый код");
    КонецЕсли;
    КонецЦикла;
    КонецЦикла;
```