Вопрос: как на клиенте найти и обработать вхождение в колонку табличной части?
...и если равно - изменить...
т.е. - надо исключичть дубли по дате в пределах секунды (дата -уникальное значение).
Интересует мнение профи - может есть более "экономичный" подход ?
Путём некоторых размышлений (будем считать, что дублей пока не было или документ новый()):
&НаКлиенте
Процедура НоменклатураПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
Если НоваяСтрока Тогда
Элементы.Номенклатура.ТекущиеДанные.Вносил = Пользователь;
Элементы.Номенклатура.ТекущиеДанные.ДатаУстановки = ТекущаяДата();
УДата = Элементы.Номенклатура.ТекущиеДанные.ДатаУстановки;
НельЗя = Истина;
Пока НельЗя Цикл
Нашел = Ложь;
Для Каждого Стр ИЗ Объект.Номенклатура Цикл
Если Стр.ДатаУстановки = УДата Тогда
УДата = УДата + 1;
Нашел = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НЕ Нашел Тогда
НельЗя = Ложь;
КонецЕсли;
КонецЦикла;
Элементы.Номенклатура.ТекущиеДанные.ДатаУстановки = УДата;
КонецЕсли;
КонецПроцедуры
Показать
Понятное дело - большинство скажет: обработай на сервере через "Найти" или "НайтиСтроки" (или ещё лучше - выгрузить, свернуть). Скидывать обработку на сервер не вижу смысла, т.е. пытаюсь оптимизировать нагрузку на вышеуказанного помошника.
В идеале я конечно же написал бы в "ПередЗаписьюНаСервере", но тогда надо проверять все дубли строк по дате - соответственно возрастает нагрузка...
P.S.
Сильно не пинайте - опыта пока маловато и возможно что-то я упустил...
Если дело только в дате, то можешь засунуть строки в список значений, в представление дату в формате hh:mm:ss. Дальше упорядочиваешь по представлению, проходишься циклом по списку. Если предыдущее представление больше текущего или равно, то меняешь текущее на предыдущее + 1, в предыдущее засовываешь новое текущее. Один проход гарантировано дает результат. Даже если все даты равны.
(8) Да, дело только в дате (она является уидом для регистра сведений).
Спасибо за подсказку - подстегнула к идеальному (на мой взгляд) решению:
&НаКлиенте
Процедура НоменклатураПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
Если НоваяСтрока Тогда
Элементы.Номенклатура.ТекущиеДанные.Вносил = Пользователь;
УДата = ТекущаяДата();
СпЗнач = Новый СписокЗначений;
Для Каждого Стр ИЗ Объект.Номенклатура Цикл
СпЗнач.Добавить(Стр.ДатаУстановки);
КонецЦикла;
СпЗнач.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
Если СпЗнач.Количество() > 0 Тогда
Если УДата <= СпЗнач[0].Значение Тогда //Вероятность совпадения 2-5% при методе "Скопировать" строку
УДата = СпЗнач[0].Значение + 1;
КонецЕсли;
КонецЕсли;
СпЗнач.Очистить();
Элементы.Номенклатура.ТекущиеДанные.ДатаУстановки = УДата;
КонецЕсли;
КонецПроцедуры
НайденныеСтроки = ТабличнаяЧасть.НайтиСтроки(Новый Структура("ДатаУстановки", НужнаяДата));
Если НайденныеСтроки.Количество() > 1 Тогда
НайденныеСтроки.Удалить(0);
Н = 1;
Для Каждого Строка ИЗ НайденныеСтроки Цикл
Строка.ДатаУстановки = Строка.ДатаУстановки + Н;
Н = Н + 1;
КонецЦикла;
КонецЕсли;
Если дело только в дате, то можешь засунуть строки в список значений, в представление дату в формате hh:mm:ss. Дальше упорядочиваешь по представлению, проходишься циклом по списку. Если предыдущее представление больше текущего или равно, то меняешь текущее на предыдущее + 1, в предыдущее засовываешь новое текущее. Один проход гарантировано дает результат. Даже если все даты равны.
(8) Да, дело только в дате (она является уидом для регистра сведений).
Спасибо за подсказку - подстегнула к идеальному (на мой взгляд) решению:
&НаКлиенте
Процедура НоменклатураПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)
Если НоваяСтрока Тогда
Элементы.Номенклатура.ТекущиеДанные.Вносил = Пользователь;
УДата = ТекущаяДата();
СпЗнач = Новый СписокЗначений;
Для Каждого Стр ИЗ Объект.Номенклатура Цикл
СпЗнач.Добавить(Стр.ДатаУстановки);
КонецЦикла;
СпЗнач.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
Если СпЗнач.Количество() > 0 Тогда
Если УДата <= СпЗнач[0].Значение Тогда //Вероятность совпадения 2-5% при методе "Скопировать" строку
УДата = СпЗнач[0].Значение + 1;
КонецЕсли;
КонецЕсли;
СпЗнач.Очистить();
Элементы.Номенклатура.ТекущиеДанные.ДатаУстановки = УДата;
КонецЕсли;
КонецПроцедуры
(1) Делай сразу в ДатаУстановкиПриИзменении методом НайтиСтроки, если массив Количество больше 1 (одна запись - это твоя проверяемая) - меняй дату, нет - остается установленная. И никаких циклов не надо
Если бы это были алгоритмы - алгоритмички если только. И они должны быть на клиенте, чтобы не дергать сервер механизмами проверки вводимых пользователем значений. Таким алгоритмичкам на сервере уж точно делать нечего.
(23) При добавлении нет. Только то, что нужно отобразить на клиенте (плюс технологический запас - несколько предшедствующих не поместившихся на экране).
Это у 1С никак не регламентируется в плане порций. Сколько там на клиенте будет, сколько на сервере останется - вопрос. Но если человек вводит в форму данные, и начинает их вводить с первой строки, то все эти строки останутся на клиенте до момента первого серверного вызова, сами они туда не поедут. По крайней мере я нигде не нашел серверных вызовов при вводе и десяти тысяч строк в форму.
Так что все очень пространно тут.
Вообще, народ с тысячами строк работает, и пока нет контекстного серверного вызова, все летает. А как только появился - пипец. Особенно лагает табличный документ. И что только отображаемую часть 1С на сервер тащит - сомневаюсь. Иначе скорость работы табличного документа 100х100 не отличалась бы от скорости работы 1000х100, а она очень отличается.
Вообще, если у тебя там ноль строк и ты вводишь строку каждые Х секунд, а иногда и дважды (что прямо следует из описания задачи), то это предполагает, что строки откуда-то приезжают. Ну, например, со сканера или из прочих внешних источников. И они у нас все тут, на клиенте, ибо они тут, на клиенте, введены вот прям сейчас.
И что будет, если мы каждый ввод будем бегать на сервер? Правильно, туда будет уезжать весь контекст всей формы. И если у человека проблема с одной и той же секундой в данных, то представляю, сколько будет серверных вызовов, которые 1С в соседних статьях категорически предлагает снизить до условного нуля.
Разные кейсы предполагают разные решения. Если 1С предлагает при проверке каких-то значений ездить на сервер, таща туда всю форму, то только от того, что 1С предполагает, что открыл пользователь форму с 20+ строками и что-то там проверить хочет, а не новую строку ввести, которая вводится в конец списка, что априори вызовет чтение всех данных на клиент. Т.е. мы уже все эти данные прочитали, нет никакого смысла бегать на сервер за ними еще раз.
Но если у нас на форме есть какое-нить сумма/среднее/количество строк, то при открытии этой формы действительно лучше получить эти данные в процедуре ПриСозданииНаСервере сразу и отобразить, а не делать это потом с клиента. Ну или вводить что-то в другие таблицы с нуждой проверить вводимое в большой таблице с каким-то условным "словарем".
открыли документ и добавляют к уже имеющимся не рассматривается?
И что происходит при добавлении новой строки на клиенте? Откуда клиент знает номер новой строки? Ты вообще представляешь, как это все там внутри платформы реализовано?
Тонкий клиент - это "веб-страница", условно. Но сделана в 1С. Зачем? Чтобы не мучаться с веб-клиентом. И да, в вебе предполагается, что есть пагинация, когда коллекция запрашивается с сервера по офсету и лимиту, т.е. запрашивается диапазон от Х до У. Но пагинация - это отображение только запрошенных строк, а у 1С это таблица формы, в которой ты можешь спозиционироваться на любую строку, выполнить отбор строк, что-то еще с ней сделать, что предполагает передачу всего контекста коллекции на клиент. И вот что-то я сильно сомневаюсь, что при вводе новой строки система получает только такое количество строк с конца, которое влезает на форму, чтобы ниже отобразить последнюю строку, в которую осуществляется ввод. Но если так, то 1С - это худшая архитектура, которую я видел, ибо затраты по передаче коллекции строк даже на тыщу строк не выше, чем на десять, т.к. пакеты в современных сетях ездят быстро. И экономить память клиента нет никакого смысла - там ее 8+ гигов уже почти везде. Да и сколько ее там сэкономится? Пару мегабайт?
ЗЫ: и даже если 1С передает эту маленькую пачку строк, а при НайтиСтроки всю пачку, то я не вижу разницы вот вообще между передачей 10 строк и 1000. Даже 100 Мбит/с нивелирует это до неразличимого органолептически отрезка времени. Особенно на фоне передачи полного контекста формы при серверном вызове в обе стороны.
Форма нужна для отображения данных. В данном случае самый экономичный вариант на мой взгляд при получении заполнения таблицы сортировать ее по дате, сохранить в переменную последнюю дату полученную в строках таблицы, а далее при добавлении новой строчки добавлять +1 к каждой последующей.