Как на клиенте найти и обработать вхождение в колонку табличной части? ...и если равно - изменить.. т.е. - надо исключичть дубли...

1. fratz 13.02.25 00:43 Сейчас в теме
Вопрос: как на клиенте найти и обработать вхождение в колонку табличной части?

...и если равно - изменить...

т.е. - надо исключичть дубли по дате в пределах секунды (дата -уникальное значение).

Интересует мнение профи - может есть более "экономичный" подход ?

Путём некоторых размышлений (будем считать, что дублей пока не было или документ новый()):

&НаКлиенте
Процедура НоменклатураПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
	
	Если НоваяСтрока Тогда
		Элементы.Номенклатура.ТекущиеДанные.Вносил = Пользователь;
		Элементы.Номенклатура.ТекущиеДанные.ДатаУстановки = ТекущаяДата();
		УДата = Элементы.Номенклатура.ТекущиеДанные.ДатаУстановки;
		НельЗя = Истина;
		Пока НельЗя Цикл
			Нашел = Ложь;
			Для Каждого Стр ИЗ Объект.Номенклатура Цикл
				Если Стр.ДатаУстановки = УДата Тогда
					УДата = УДата + 1;
					Нашел = Истина;
					Прервать;
				КонецЕсли;
			КонецЦикла;
			Если НЕ Нашел Тогда
				НельЗя = Ложь;
			КонецЕсли;
		КонецЦикла;
		Элементы.Номенклатура.ТекущиеДанные.ДатаУстановки = УДата;
	КонецЕсли;
	
КонецПроцедуры
Показать


Понятное дело - большинство скажет: обработай на сервере через "Найти" или "НайтиСтроки" (или ещё лучше - выгрузить, свернуть). Скидывать обработку на сервер не вижу смысла, т.е. пытаюсь оптимизировать нагрузку на вышеуказанного помошника.

В идеале я конечно же написал бы в "ПередЗаписьюНаСервере", но тогда надо проверять все дубли строк по дате - соответственно возрастает нагрузка...


P.S.

Сильно не пинайте - опыта пока маловато и возможно что-то я упустил...
Найденные решения
8. starik-2005 3165 13.02.25 13:35 Сейчас в теме
(4)
поменял дату, а она уже стала пересекаться
Если дело только в дате, то можешь засунуть строки в список значений, в представление дату в формате hh:mm:ss. Дальше упорядочиваешь по представлению, проходишься циклом по списку. Если предыдущее представление больше текущего или равно, то меняешь текущее на предыдущее + 1, в предыдущее засовываешь новое текущее. Один проход гарантировано дает результат. Даже если все даты равны.
11. fratz 13.02.25 19:10 Сейчас в теме
(8) Да, дело только в дате (она является уидом для регистра сведений).
Спасибо за подсказку - подстегнула к идеальному (на мой взгляд) решению:
&НаКлиенте
Процедура НоменклатураПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
	Если НоваяСтрока Тогда
		Элементы.Номенклатура.ТекущиеДанные.Вносил = Пользователь;
		УДата = ТекущаяДата();
		СпЗнач = Новый СписокЗначений;
		Для Каждого Стр ИЗ Объект.Номенклатура Цикл
			СпЗнач.Добавить(Стр.ДатаУстановки);
		КонецЦикла;
		СпЗнач.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
		Если СпЗнач.Количество() > 0 Тогда
			Если УДата <= СпЗнач[0].Значение Тогда //Вероятность совпадения 2-5% при методе "Скопировать" строку
				УДата = СпЗнач[0].Значение + 1;
			КонецЕсли;
		КонецЕсли;
		СпЗнач.Очистить();
		Элементы.Номенклатура.ТекущиеДанные.ДатаУстановки = УДата;
	КонецЕсли;
КонецПроцедуры
Показать
26. fratz 13.02.25 21:32 Сейчас в теме
(25) Тогда вообще получается проще при создании на сервере вычислить наибольшую дату и передать на клиента, а там уже с ней и работать...
29. SlavaKron 13.02.25 23:02 Сейчас в теме
(26) Верно. В этом случае вам не придется обходить всю ТЧ делать из-за этого серверный вызов.
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
25. SlavaKron 13.02.25 21:23 Сейчас в теме
(1)
Скидывать обработку на сервер не вижу смысла, т.е. пытаюсь оптимизировать нагрузку на вышеуказанного помошника.
Это называется "Преждевременная оптимизация", которая в итоге сделала только хуже. Тут https://its.1c.ru/db/pubv8devui#content:297:hdoc подробнее про работу с данными коллеций форм.
26. fratz 13.02.25 21:32 Сейчас в теме
(25) Тогда вообще получается проще при создании на сервере вычислить наибольшую дату и передать на клиента, а там уже с ней и работать...
29. SlavaKron 13.02.25 23:02 Сейчас в теме
(26) Верно. В этом случае вам не придется обходить всю ТЧ делать из-за этого серверный вызов.
2. user2107191 13.02.25 07:27 Сейчас в теме
Ну и зачем тебе два цикла? И зачем ты его прерываешь как только нашел одну подходящую дату в ТЧ Номенклатура? А если таких дат несколько?
5. fratz 13.02.25 11:35 Сейчас в теме
(2) Мысль следующая: при изменении есть возможность пересечься с уже пройденными строками...
На счёт прервывания - согласен, скорее это лишнее...
3. starik-2005 3165 13.02.25 07:38 Сейчас в теме
НайденныеСтроки = ТабличнаяЧасть.НайтиСтроки(Новый Структура("ДатаУстановки", НужнаяДата));
Если НайденныеСтроки.Количество() > 1 Тогда
  НайденныеСтроки.Удалить(0);
  Н = 1;
  Для Каждого Строка ИЗ НайденныеСтроки Цикл
    Строка.ДатаУстановки =  Строка.ДатаУстановки + Н;
    Н = Н + 1;
  КонецЦикла;
КонецЕсли;
Показать
4. fratz 13.02.25 11:30 Сейчас в теме
(3) Получается что надо ещё в один цикл оборачивать - поменял дату, а она уже стала пересекаться с другой - вне "НайденныеСтроки".
6. vadim1011985 103 13.02.25 11:44 Сейчас в теме
(4) Так загоняй обработанные даты в соответствие и прежде чем менять проверяй новую дату если обработана она или еще нет
8. starik-2005 3165 13.02.25 13:35 Сейчас в теме
(4)
поменял дату, а она уже стала пересекаться
Если дело только в дате, то можешь засунуть строки в список значений, в представление дату в формате hh:mm:ss. Дальше упорядочиваешь по представлению, проходишься циклом по списку. Если предыдущее представление больше текущего или равно, то меняешь текущее на предыдущее + 1, в предыдущее засовываешь новое текущее. Один проход гарантировано дает результат. Даже если все даты равны.
11. fratz 13.02.25 19:10 Сейчас в теме
(8) Да, дело только в дате (она является уидом для регистра сведений).
Спасибо за подсказку - подстегнула к идеальному (на мой взгляд) решению:
&НаКлиенте
Процедура НоменклатураПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
	Если НоваяСтрока Тогда
		Элементы.Номенклатура.ТекущиеДанные.Вносил = Пользователь;
		УДата = ТекущаяДата();
		СпЗнач = Новый СписокЗначений;
		Для Каждого Стр ИЗ Объект.Номенклатура Цикл
			СпЗнач.Добавить(Стр.ДатаУстановки);
		КонецЦикла;
		СпЗнач.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
		Если СпЗнач.Количество() > 0 Тогда
			Если УДата <= СпЗнач[0].Значение Тогда //Вероятность совпадения 2-5% при методе "Скопировать" строку
				УДата = СпЗнач[0].Значение + 1;
			КонецЕсли;
		КонецЕсли;
		СпЗнач.Очистить();
		Элементы.Номенклатура.ТекущиеДанные.ДатаУстановки = УДата;
	КонецЕсли;
КонецПроцедуры
Показать
15. user1936660 13.02.25 19:39 Сейчас в теме
(11)
УДата = ТекущаяДата();

Используй ПолучитьОперативнуюОтметкуВремени() и таки не имей никому голову.
16. fratz 13.02.25 19:43 Сейчас в теме
(15)
Используй ПолучитьОперативнуюОтметкуВремени() и таки не имей никому голову.


Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный
7. polax 13.02.25 11:53 Сейчас в теме
(1) Делай сразу в ДатаУстановкиПриИзменении методом НайтиСтроки, если массив Количество больше 1 (одна запись - это твоя проверяемая) - меняй дату, нет - остается установленная. И никаких циклов не надо
9. Asgard90 13.02.25 13:38 Сейчас в теме
Экономить сервер, и городить хоть какие-то алгоритмы на клиенте, уже так себе подход если честно
10. starik-2005 3165 13.02.25 13:48 Сейчас в теме
(9)
и городить хоть какие-то алгоритмы на клиенте
Если бы это были алгоритмы - алгоритмички если только. И они должны быть на клиенте, чтобы не дергать сервер механизмами проверки вводимых пользователем значений. Таким алгоритмичкам на сервере уж точно делать нечего.
user2107191; +1 Ответить
12. spacecraft 13.02.25 19:23 Сейчас в теме
(10)
И они должны быть на клиенте, чтобы не дергать сервер

э... типо тащить все строки на клиент выгоднее?
13. user2107191 13.02.25 19:38 Сейчас в теме
(12) Какие строки? Тут уже теоретическая ветка пошла, начиная с (9)
17. spacecraft 13.02.25 20:04 Сейчас в теме
(13) те, которые в (8) упоминаются.
19. user2107191 13.02.25 20:14 Сейчас в теме
(17) Так это в другой ветке, которая про практическую задачу автора.
20. spacecraft 13.02.25 20:19 Сейчас в теме
(19) так тема одна. контекст один. Про "алгоритмички" с привязкой к чему? Как минимум к коду в шапке:
Для Каждого Стр ИЗ Объект.Номенклатура Цикл

А, знаю, новомодное выражение: "Это другое" )))
21. user2107191 13.02.25 20:23 Сейчас в теме
(20)
Про "алгоритмички" с привязкой к чему?
Вот к этому
Экономить сервер, и городить хоть какие-то алгоритмы на клиенте, уже так себе подход если честно
22. spacecraft 13.02.25 20:26 Сейчас в теме
(21) вот так тупо без привязки?
И это был ответ на код в шапке. Значит как минимум контекст был. Код был. Строки были.
14. fratz 13.02.25 19:39 Сейчас в теме
(12)
э... типо тащить все строки на клиент выгоднее?


Строки и так уже на клиенте в копии "Объект.ТабличнаяЧасть". Это не динамический список...
18. spacecraft 13.02.25 20:05 Сейчас в теме
23. fratz 13.02.25 20:33 Сейчас в теме
(18) Клиент так, или иначе потащит к себе эти строки при прокрутке или добавлении новых, т.к. новые добавляются в конец списка
24. spacecraft 13.02.25 20:49 Сейчас в теме
(23) При добавлении нет. Только то, что нужно отобразить на клиенте (плюс технологический запас - несколько предшедствующих не поместившихся на экране).
27. fratz 13.02.25 21:33 Сейчас в теме
(24) Тогда вообще получается проще при создании на сервере вычислить наибольшую дату и передать на клиента, а там уже с ней и работать...
32. spacecraft 14.02.25 06:13 Сейчас в теме
(27) это наиболее правильное решение.
28. starik-2005 3165 13.02.25 22:18 Сейчас в теме
(24)
Только то, что нужно отобразить на клиенте
Это у 1С никак не регламентируется в плане порций. Сколько там на клиенте будет, сколько на сервере останется - вопрос. Но если человек вводит в форму данные, и начинает их вводить с первой строки, то все эти строки останутся на клиенте до момента первого серверного вызова, сами они туда не поедут. По крайней мере я нигде не нашел серверных вызовов при вводе и десяти тысяч строк в форму.

Так что все очень пространно тут.

Вообще, народ с тысячами строк работает, и пока нет контекстного серверного вызова, все летает. А как только появился - пипец. Особенно лагает табличный документ. И что только отображаемую часть 1С на сервер тащит - сомневаюсь. Иначе скорость работы табличного документа 100х100 не отличалась бы от скорости работы 1000х100, а она очень отличается.
31. spacecraft 14.02.25 06:12 Сейчас в теме
(28) стандарты разработки подойдут?
https://its.1c.ru/db/v8std#content:628:hdoc

Еще где-то есть про точное количество, искать нет желания.
34. starik-2005 3165 14.02.25 12:04 Сейчас в теме
(31)
нужно ориентироваться на количество от 20 строк
Если меньше, то можно?

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

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

Разные кейсы предполагают разные решения. Если 1С предлагает при проверке каких-то значений ездить на сервер, таща туда всю форму, то только от того, что 1С предполагает, что открыл пользователь форму с 20+ строками и что-то там проверить хочет, а не новую строку ввести, которая вводится в конец списка, что априори вызовет чтение всех данных на клиент. Т.е. мы уже все эти данные прочитали, нет никакого смысла бегать на сервер за ними еще раз.

Но если у нас на форме есть какое-нить сумма/среднее/количество строк, то при открытии этой формы действительно лучше получить эти данные в процедуре ПриСозданииНаСервере сразу и отобразить, а не делать это потом с клиента. Ну или вводить что-то в другие таблицы с нуждой проверить вводимое в большой таблице с каким-то условным "словарем".
35. spacecraft 14.02.25 12:16 Сейчас в теме
(34) т.е. рассматривается, только ввод новых строк в новый документ?
А кейсы, что открыли документ и добавляют к уже имеющимся не рассматривается?
36. starik-2005 3165 14.02.25 13:09 Сейчас в теме
(35)
открыли документ и добавляют к уже имеющимся не рассматривается?
И что происходит при добавлении новой строки на клиенте? Откуда клиент знает номер новой строки? Ты вообще представляешь, как это все там внутри платформы реализовано?

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

ЗЫ: и даже если 1С передает эту маленькую пачку строк, а при НайтиСтроки всю пачку, то я не вижу разницы вот вообще между передачей 10 строк и 1000. Даже 100 Мбит/с нивелирует это до неразличимого органолептически отрезка времени. Особенно на фоне передачи полного контекста формы при серверном вызове в обе стороны.
30. Asgard90 14.02.25 04:13 Сейчас в теме
Форма нужна для отображения данных. В данном случае самый экономичный вариант на мой взгляд при получении заполнения таблицы сортировать ее по дате, сохранить в переменную последнюю дату полученную в строках таблицы, а далее при добавлении новой строчки добавлять +1 к каждой последующей.
33. fratz 14.02.25 08:15 Сейчас в теме
(30) Уже пришли к этому выводу в (26) и (29)...
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот