Имя: Пароль:
1C
1С v8
Обработка выбора в ТаблицеФормы - открыть элемент справочника
0 zelenprog
 
04.07.23
12:55
У внешней обработки есть реквизит ДЗКонтрагенты - "ДеревоЗначений".
На форме ему "соответствует" элемент формы - ТаблицаФормы.
Для этой таблицы сделал процедуру для обработки события "Выбор". При срабатывании этого события (неважно на какой ячейке) нужно открыть контрагента из ячейки "Контрагент".

Сейчас я сделал так:


&НаСервере
Процедура ПолучитьСтрокуДЗПоИдентификатору_НаСервере (пИдТекущейСтроки, пЕстьТекСтрока, пТекСтрока)

    лДЗ = ДЗКонтрагенты;
    
    пЕстьТекСтрока = Ложь;
    пТекСтрока = Неопределено;
    
    лТекущаяСтрока = лДЗ.НайтиПоИдентификатору(пИдТекущейСтроки);
    Если лТекущаяСтрока = Неопределено Тогда
        Сообщить("Не найдена текущая строка на сервере!");
    Иначе
        пТекСтрока = лТекущаяСтрока;
        пЕстьТекСтрока = Истина;
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Функция ПолучитьКонтрагентаПоТекущейСтроке_НаСервере (пИдТекущейСтроки)
    
    лЕстьТекСтрока = 0;
    лТекСтрока = 0;
    ПолучитьСтрокуДЗПоИдентификатору_НаСервере(пИдТекущейСтроки, лЕстьТекСтрока, лТекСтрока);
    
    лКонтрагент = Неопределено;
    лСтруктура = Новый Структура;
    Если лЕстьТекСтрока = Истина Тогда
        лКонтрагент = лТекСтрока.Контрагент;
    КонецЕсли;
    лСтруктура.Вставить("Контрагент", лКонтрагент);
    
    Возврат лСтруктура;
    
КонецФункции

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

&НаКлиенте
Процедура эфДЗКонтрагентыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ПоказатьКонтрагентаТекущейСтроки(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка);
КонецПроцедуры


Правильно ли это с точки зрения архитектуры?
1 zelenprog
 
04.07.23
13:05
Может быть можно как-то сделать попроще?
2 Мультук
 
04.07.23
13:17
(1)

Можно, но для этого нужно включить отладчик и {вычеркнуто цензурой}

&НаКлиенте
Процедура ДеревоРезервовВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    ТекущиеДанные = Элементы.ДеревоРезервов.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    Если Элемент.ТекущийЭлемент.Имя     = "ДеревоРезервовСсылкаНаДокумент" Тогда
        СтандартнаяОбработка = Ложь;
        
        ПоказатьЗначение(, ТекущиеДанные.СсылкаНаДокумент);
    КонецЕсли;    
    
КонецПроцедуры
3 zelenprog
 
04.07.23
13:24
(2) У меня ситуация чуть сложнее.
В ТаблицуФормы колонка с контрагентом не выведена. Колонка "Контрагент" есть только в ДеревеЗначений.
4 zelenprog
 
04.07.23
13:27
Как в этом случае достать контрагента?
5 Мультук
 
04.07.23
13:53
(3)

В ТаблицуФормы колонка с контрагентом не выведена
Как в этом случае достать контрагента?

Включите в дереве у реквизита контрагент флажок "Использовать всегда".
Он ставится всем новым реквизитам дерева, но либо вы его выключили, либо даже не тестили
6 zelenprog
 
04.07.23
14:08
(5) Флажок включен.
Просто я специально удалил этот реквизит из элементов формы.
Он для отображения не нужен. А вот для открытия при щелчке на строке - нужен.

Как лучше сделать? Добавить контрагента в элементы формы?
Или доставать его из ДереваЗначений как у меня сделано?
7 Мультук
 
04.07.23
14:15
(6)

Скажи честно, ты тестил, то что я тебе написал ?
Смотрел в отладчике ?

Ибо я -тестил. И в моей тестовой обработке реквизита на форме нет, но его значение я достаю.
8 zelenprog
 
04.07.23
14:27
(7) Нет, не тестил. Я почему-то думал, что там есть доступ только к тем реквизитам ДереваЗначений, которые добавлены как элементы формы.
Сейчас потестирую.
9 zelenprog
 
05.07.23
09:23
(7) Я проверил в отладчике.
Действительно, данные ДереваЗначений доступны через "Элемент.ТекущиеДанные".
В том примере, который я описал выше - это сработает. Однако, тот пример был упрощенный, когда нужный Контрагент, которого нужно открыть, есть в текущей строке.

А теперь реальный пример.
В узле дерева есть несколько строк (количество строк может быть разным). Все эти строки имеют отношение к одному контрагенту в базе.
Несколько строк, которые добавляются в узел, (может быть от нуля до трех таких строк) - это данные из внешних файлов-выгрузки с информацией о контрагенте. Эти файлы - это выгрузка контрагентов из старых баз. Три параллельно работающие старые базы могут содержать одного и того же контрагента, поэтому этот контрагент может попасть в три файла выгрузки. Эти "информационные" строки не содержат ссылки на контрагента из текущей базы.
Затем по ИНН + КПП из этих "информационных" строк ищем контрагента(-ов) в текущей базе.
Чаще всего в текущей базе соответствует один контрагента, и добавляем строку с этим контрагентом в узел. Если найдено несколько контрагентов, то их всех добавляем в узел.
Сам узел (строка узла) содержит просто ячейки ИНН и КПП.

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

Как правильно сделать в этой ситуации?
Делать поиск нужной строки по ДеревуЗначений-источнику?
10 Admin_Net_1C
 
05.07.23
09:36
(9) как вариант: формируем кэш контрагентов текущей базы (соответствие: ключ=ИНН+КПП; значение=массив контрагентов текущей базы с соответствующими ИНН и КПП), далее из этого кэша получаем по ключу контрагентов текущей базы (значение)
11 zelenprog
 
05.07.23
10:07
(10) Да, вариант подходящий.
А где хранить этот кэш контрагентов? В реквизите объекта обработки? Или в реквизите формы?

В какой процедуре выполнять поиск по кэшу? В процедуре &НаСервере или &НаКлиенте?
12 Мультук
 
05.07.23
10:07
(9)

>> Получается, ссылки на контрагента может не быть в текущей строке. Нужно выполнять поиск контрагента по всем строкам текущего узла.

В чем проблема
а) Определить на каком уровне дерева мы находимся.
б) Если на верхнем -- перебрать "детей"
в) Почему бы при заполнении детей, если "контрагент" один, заполнить его у родителя, чтобы потом не заниматься поисками ?
13 zelenprog
 
05.07.23
10:14
В итоге ведь все равно получается, что отдельно есть две "вещи":
- отображение-представление ДереваЗначений на форме,
- и есть некие "исходные" данные, которые не нужны при отображении, но используются при выполнении действий с отображением.

Поэтому приходится как-то организовать "связку" между этими двумя "вещами".
14 zelenprog
 
05.07.23
10:16
(12) >> Если на верхнем -- перебрать "детей"

Это можно сделать на клиенте для Элемента формы?

>> Почему бы при заполнении детей, если "контрагент" один, заполнить его у родителя, чтобы потом не заниматься поисками ?

Да. Так можно сделать.
15 zelenprog
 
05.07.23
10:18
Но продолжая вопрос про две "вещи" (отображение-представление и "исходные" данные)...
Правильно ли все данные, необходимые при выполнении действий, "пихать" в реквизиты отображения?

Это похоже на извечный вопрос о разделении интерфейса и обработки данных.
Когда-то давно на С++ даже использовался такой шаблон - MVP - Model-View-Presenter.
Насколько это применимо к 1С. И как это реализуется на 1С?

Может быть достаточно при отображении хранить некую "связку" с исходными данными?
Имеет место быть такой подход в 1С?
16 Мультук
 
05.07.23
10:34
(14)
>>>> Если на верхнем -- перебрать "детей"
>> Это можно сделать на клиенте для Элемента формы?

Вы снова не хотите читать и разбираться самостоятельно ? Напрасно.
Ответ: ДА

(15)

Допустим у вас на форме таблица значений (или дерево не важно) в 50 тыс строк. 10 колонок.
Объясните мне (точнее себе) "на пальцах", почему в этом случае нужно стараться использовать

&НаКлиенте
&НаСервереБезКонтекста

и почему использование "без причины"
&НаСервере

это плохо?
17 zelenprog
 
05.07.23
11:08
(16) >> Вы снова не хотите читать и разбираться самостоятельно ? Напрасно.
Ответ: ДА

Хорошо, спасибо. Буду разбираться. Понимание, что это можно сделать - воодушевляет на изучение.
18 zelenprog
 
05.07.23
11:16
(16)
>> и почему использование "без причины"
>> &НаСервере
>> это плохо?

Продолжая ваш пример...
Допустим, дерево содержит 100 колонок. И с деревом можно выполнить 50 разных операций, для которых нужны все эти 100 колонок.
Однако, пользователю все 100 колонок не нужно видеть, ему нужно видеть только 3 "идентификационные" колонки.

Если делать это дерево доступным для показа пользователю, то мне нужно будет все 100 колонок прописать в конфигураторе.

Если же это дерево не показывать и просто иметь его в качестве "источника" данных, то можно в конфигураторе создать "пользовательское" дерево только с 3-мя нужными ему колонками. И загружать его данными из дерева-источника.
Но при этом надо придумать и сделать "связь" между ними.
19 zelenprog
 
09.07.23
07:20
(16),(18)
Вот попалась старая тема по похожему вопросу:
Оптимизация поиска в УФ с большим числом строк. Как в УФ хранить ТЗ только на сервере?

Там предлагают хранить большую ТЗ во временном хранилище на сервере.
20 Мимохожий Однако
 
09.07.23
08:23
Обсуждение навеяло фразу: "Гараж-то откройте"
21 zelenprog
 
09.07.23
12:22
(20) Что ты имел ввиду?
22 Мультук
 
09.07.23
13:04
(21)

Вопросы:
1) Сколько строк в вашей таблице (дереве). Сколько колонок?
2) Вы так и не ответили на вопрос:

Допустим у вас на форме таблица значений (или дерево не важно) в 50 тыс строк. 10 колонок.
Объясните мне (точнее себе) "на пальцах", почему в этом случае нужно стараться использовать

&НаКлиенте
&НаСервереБезКонтекста

и почему использование "без причины"
&НаСервере

это плохо?

3) Что такое для вас "Много строк" ? Одна, десять, тысяча ? 10 тыс ? Сколько ?
Только не нужно брать число с потолка.
23 zelenprog
 
09.07.23
14:34
(22)
>> Сколько строк в вашей таблице (дереве). Сколько колонок?

Строк около 8 тыс. Колонок около 30. Это пока.
Затем при расширении функциональности обработки к ним будут добавляться другие строки из других справочников.

>> Вы так и не ответили на вопрос:
>> почему ... нужно стараться использовать &НаКлиенте &НаСервереБезКонтекста
>> и почему использование "без причины" &НаСервере это плохо?

Я выше ответил на этот вопрос. Может быть не четко и как-то сумбурно.

Вот более точный ответ:

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

2) Вторая причина - это "теоретическая", речь как раз об используемом подходе.
Нас учили, что даже в программе из 20 строк, надо логически разделять модули по назначению: работа с данными - отдельно, работа с пользовательским интерфейсом - отдельно.
Да, на этапе разработки такой "архитектуры" программист затратит лишние 1-2 часа на ее обдумывание.
Однако, в дальнейшем эти трудозатраты окупятся.
24 Мультук
 
09.07.23
15:33
(23)

С 8 тыс строк можно просто "забить" на вашу псведо-оптимизацию.

Каждый раз когда вы вызываете функцию "наСервере" все эти 8 тыс строк и (не знаю сколько у вас колонок) 1С отправляет на сервер,
а затем получает обратно.

https://its.1c.ru/db/v8std/content/636/hdoc
https://its.1c.ru/db/pubv8devui/content/189/hdoc

P.S.
Почитайте ИТС там много нужного и интересного.
25 zelenprog
 
09.07.23
16:18
(24) Это все я понимаю. Я понимаю, что можно "забить".

Но мой вопрос связан не только с данной конкретной задачей.

Мой вопрос более "широкий".
Как вообще при необходимости нужно по "правильному" делать такую "оптимизацию"?
Чтобы это была не "псевдо"-оптимизация, а чтобы это была настоящая оптимизация.
Вы не отвечаете на этот вопрос, и обходите его стороной.
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс