Здравствуйте!
УТП 8.3, обычные формы
Есть такая проблема:
В документе "Заказ покупателя" дописана Табличная часть "Расшифровка", куда выгружаются с Битрикс задачи и их подзадачи(колонки: Задача, ID, Исполнитель, Количество часов, Цена). Выгрузка происходит в модуле объекта. Я бы хотел, чтобы при заполнении каждой задачи сделать проверку как-то запросом по всех проведенных документах и их табличной части "Расшифровка" . Чтобы узнать есть ли по этой задаче ранее проведенное какое-то время и если есть, то получить его и минусовать от полученого с выгрузки.
Я не понимаю как это лучше сделать.
Механизм заполнения:

```1c
    Для ЭлементРезультата = 0 По Результат.result.tasks.Количество()-1 Цикл
    Если Результат.result.tasks[ЭлементРезультата].groupId = Контрагент.IDКлиентаВБитрикс Тогда
    НоваяСтрока = Расшифровка.Добавить();
    НоваяСтрока.Задание = Результат.result.tasks[ЭлементРезультата].title;
    НоваяСтрока.ID = Результат.result.tasks[ЭлементРезультата].ID;
    НоваяСтрока.IDРодителя = Результат.result.tasks[ЭлементРезультата].parentId;
    НоваяСтрока.Исполнитель = Результат.result.tasks[ЭлементРезультата].responsible.name;
    НоваяСтрока.КоличествоЧасов = Результат.result.tasks[ЭлементРезультата].timeSpentInLogs;
    НоваяСтрока.КоличествоЧасов = НоваяСтрока.КоличествоЧасов / 3600;
    НоваяСтрока.Цена = НоваяСтрока.КоличествоЧасов * ЦенаПолучить;
    КонецЕсли;
    КонецЦикла;
```
---
1. Если объем базы большой - сделайте регистр сведений, где будете хранить ИД задачи и количество часов. При проведении заявки пишите в этот регистр, при контроле делайте запрос к нему. При большом объеме документов запрос к табличной части документов гарантировано "умрет", к регистру вполне будет работать. Причем именно регистр сведений (т.к. это самая быстрая таблица в 1С), а суммировать и в запросе можно и отработает это быстро.
2. Если ИД имеет тип "Строка" используйте в запросе " ВЫРАЗИТЬ(ЗаказПокупателяРасшифровка.ID КАК СТРОКА(100)) = ВЫРАЗИТЬ(&ИД КАК СТРОКА(100))". При прямом сравнении в случае, если длина строки динамическая, условие может не отработать и результат запроса будет пустой, так отработает точно.
---
Если поиск по ИД, то все загружаемые ИД в массив и из базы вибираете задачи с вхождением в этот массив, все что нашлось вам не надо.
---
но может быть, что ранее задача была проведена на 3 часа, а по ней теперь выгрузилось 8 и мне бы надо её не отсеять, а оставить 5 часов
---
продолжить предложенное в (2)
поиск по ID, вернуть результат в виде ID, Задание, Исполнитель, КоличествоЧасов. Будет таблица ранее загруженных данных по ID.
Далее при загрузке искать среди загруженных ранее по ID и вычитать из загружаемых часов ранее загруженные часы.
Не забыть пересчитать и Цена. А еще проверять, что КоличествоЧасов - КоличествоЧасовРанее <=0, типа дважды отчитались по одной и той же задаче.
---
в таком случае думаю лучше использовать регистр накопления, чтобы получить остаток, и на разницу посадить новые данные
---
тогда придется его создать, я думал что можно как-то из табличных частей документов вытащить это
Я пытался так, но не вышло:

```1c
    Процедура ПроверкаИДЗадачи(ИД)

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | ЗаказПокупателяРасшифровка.КоличествоЧасов КАК КоличествоЧасов
    |ИЗ
    | Документ.ЗаказПокупателя.Расшифровка КАК ЗаказПокупателяРасшифровка
    |ГДЕ
    | ЗаказПокупателяРасшифровка.ID = &ИД";
    Запрос.УстановитьПараметр("ИД", ИД);

    РезультатЗапроса = Запрос.Выполнить();
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    КоличествоЧасовВыборка = 0;

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    КоличествоЧасовВыборка = КоличествоЧасовВыборка + ВыборкаДетальныеЗаписи.КоличествоЧасов;
    КонецЦикла;
    Сообщить(КоличествоЧасовВыборка);

    КонецПроцедуры
```
---
со временем это замедлит работу системы, так как объем документов у вас будет расти.
---
Добрый день!
Вопрос - актуален?
Если актуален, сразу деталь:
            НоваяСтрока.КоличествоЧасов = Результат.result.tasks[ЭлементРезультата].timeSpentInLogs;
            НоваяСтрока.КоличествоЧасов = НоваяСтрока.КоличествоЧасов / 3600;
Получается, что результат, который Вы выгружаете, изначально - дробный. А тот, который проводите ( фиксируете у себя, как сделанный) вероятнее всего - целый. Опишите, пожалуйста, формат этих двух величин, потому что, потом, будет девиация именно по этому показателю
---
Здравствуйте! Очень актуален ещё, т.к. не смог реализовать хорошее решение.
Дробный потому, что с Битрикса в секундах выгружается, я хотел в часы перевести
---
А само решение - ПроверкаИДЗадачи(ИД) , чем не устраивает? то, что при увеличении количества документов, дольше цикл будет выполняться ?
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        КоличествоЧасовВыборка = КоличествоЧасовВыборка + ВыборкаДетальныеЗаписи.КоличествоЧасов;
    КонецЦикла;
Если это пугает, напишите, есть способ это обойти

Как думаете решить :
   НоваяСтрока.КоличествоЧасов = Результат.result.tasks[ЭлементРезультата].timeSpentInLogs;
   НоваяСтрока.КоличествоЧасов = НоваяСтрока.КоличествоЧасов / 3600;
У Вас Поле количество часов - одно, а схожих показателей - 2:
КоличествоПоданныхЧасов - то, сколько отправили к защите ,
КоличествоПроведенныхЧасов - то, сколько засчитали, из поданных.
Не предполагаете завести 2 показателя ( один, который есть, КоличествоПроведенныхЧасов , и , добавить второй - КоличествоПоданныхЧасов) ?
Полезная статистика из 2-х показателей - ПроцентПринятыхЧасов ( КоличествоПроведенныхЧасов/КоличествоПоданныхЧасов) * 100 .
Чем выше ПроцентПринятыхЧасов , тем качественнее работа исполнителя
---
в моём случае ПроверкаИДЗадачи не работает, отладчиком смотрел и оказалось, что запрос результата никакого не возращает

А вы не знаете, как лучше бы реализовать перевод с секунд в часы, чтобы не делать это деление на 3600 ?
Суть в том, что я не знаю как правильно реализовать эту проверку.
Задача по сути для такого случая:
Есть задача, Исполнитель её сделал и она выгрузилась в документ(принята и оплачена). Но потом Клиент решил доделать какой-то функционал и отправил ту же задачу на доработку, на которую Исполнитель потратил ещё время. Мне бы надо узнать ранее потраченое время(с проведенных документов, сделать проверку по ID задачи) и разницу дальше выгружать. Чтобы при каждой выгрузке задач делалась эта проверка, была ли задача ранее выгружена и если да то сколько часов по ней закрыто
---
"Мне бы надо узнать ранее потраченное время"
....
   Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        | ЗаказПокупателяРасшифровка.КоличествоЧасов КАК КоличествоЧасов
        |ИЗ
        | Документ.ЗаказПокупателя.Расшифровка КАК ЗаказПокупателяРасшифровка
        |ГДЕ
        | ЗаказПокупателяРасшифровка.ID = &ИД";
    Запрос.УстановитьПараметр("ИД", ИД);

    РезультатЗапроса = Запрос.Выполнить();
    ТаблицаДетальныеЗаписи = РезультатЗапроса.Выбрать().Выгрузить();
    КоличествоЧасов = ТаблицаДетальныеЗаписи.Итог("КоличествоЧасов");

    Сообщить(КоличествоЧасов);
....
---
РезультатЗапроса = Запрос.Выполнить();
ТаблицаДетальныеЗаписи = РезультатЗапроса.Выбрать().Выгрузить();
КоличествоЧасов = ТаблицаДетальныеЗаписи.Итог("КоличествоЧасов");

{Документ.ЗаказПокупателя.МодульОбъекта(3280)}: Метод объекта не обнаружен (Выгрузить)
 ТаблицаДетальныеЗаписи = РезультатЗапроса.Выбрать().Выгрузить();
---
"в моём случае ПроверкаИДЗадачи не работает, отладчиком смотрел и оказалось, что запрос результата никакого не возвращает"
Запрос проверьте в консоли запросов
---
1. Если объем базы большой - сделайте регистр сведений, где будете хранить ИД задачи и количество часов. При проведении заявки пишите в этот регистр, при контроле делайте запрос к нему. При большом объеме документов запрос к табличной части документов гарантировано "умрет", к регистру вполне будет работать. Причем именно регистр сведений (т.к. это самая быстрая таблица в 1С), а суммировать и в запросе можно и отработает это быстро.
2. Если ИД имеет тип "Строка" используйте в запросе " ВЫРАЗИТЬ(ЗаказПокупателяРасшифровка.ID КАК СТРОКА(100)) = ВЫРАЗИТЬ(&ИД КАК СТРОКА(100))". При прямом сравнении в случае, если длина строки динамическая, условие может не отработать и результат запроса будет пустой, так отработает точно.
---
ВЫРАЗИТЬ(ЗаказПокупателяРасшифровка.ID КАК СТРОКА(100)) = ВЫРАЗИТЬ(&ИД КАК СТРОКА(100))
а как это в запрос поместить? А то я не смог сделать, выдало ошибку
---
Я не могу понять, почему в Таб ничего не попадает. Проверяю отладкой и просто пустое значение, хоть сам запрос верный
Прошу помочь, если кто-то знает в чём беда

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

    РезультатЗапроса = Запрос.Выполнить();
    Таб = РезультатЗапроса.Выгрузить();

    Для Каждого Стр Из Таб Цикл
    Сообщить(Стр.КоличествоЧасов);
    КонецЦикла;
```