Имя: Пароль:
1C
1C 7.7
v7: Поиск предыдущего документа
,
0 ДНН
 
17.10.18
13:58
Добрый день, коллеги.
1С 7.7.
Нужно найти предыдущий документ по автомобилю и взять из него значение спидометра, зная ссылку на текущий док и автомобиль.
Использую такой код:

Доки = СоздатьОбъект("Документ.ПЛАвтобуса");
Доки.ОбратныйПорядок(1);
Доки.ВыбратьДокументы();
НайденТекущийДокумент = 0;
Пока Доки.ПолучитьДокумент() = 1 Цикл
    ТекДок = Доки.ТекущийДокумент();
    Если ТекДок.Выбран() = 1 Тогда
        Если ТекДок.Проведен() = 0 Тогда
            Продолжить;
        КонецЕсли;    
        Если ТекДок.ПометкаУдаления() = 1 Тогда
            Продолжить;
        КонецЕсли;
        Если ТекДок.Автомобиль <> спрАвтомобиль Тогда
            Продолжить;
        КонецЕсли;
        Если ТекДок = докПЛ Тогда
            НайденТекущийДокумент = 1;
            Сообщить("Найден");
            Продолжить;
        КонецЕсли;
        Если НайденТекущийДокумент = 1 Тогда
             пвСпидометрНачальный=ТекДок.СпидометрВозвращения;    
        КонецЕсли;    
    КонецЕсли;    
КонецЦикла;    

Вот это условие Если ТекДок = докПЛ Тогда никогда не бывает истинным. Что делаю не так?
Есть ли более простой способ найти предыдущий документ? Если да, то какой?
Спасибо.
1 Cool_Profi
 
17.10.18
14:00
За использование запросов, я так понимаю, у вас расстреливают?
2 ДНН
 
17.10.18
14:03
(1) Предыдущий документов может быть той же датой, что и текущий. Как тогда в запросе делать отбора по дате?
3 ДНН
 
17.10.18
14:04
(1) Основной вопрос почему вот это Если ТекДок = докПЛ Тогда никогда не бывает истинным.
4 ДНН
 
17.10.18
14:04
(1) в отладчике пишет "Ошибка в выражении"
5 lubitelxml
 
17.10.18
14:06
в ДокПЛ что у тебя?
6 ДНН
 
17.10.18
14:07
(5) ссылка на документ типа Документ.ПЛАвтобуса, в отладчике корректно показывает. Это реквизит на форме
7 1Сергей
 
17.10.18
14:13
(6) попробуй докПЛ.ТекущийДокумент()
8 ДНН
 
17.10.18
14:18
Разобрался. Текущий документ не был проведен, поэтому не находился.
9 ДНН
 
17.10.18
14:18
Всем спасибо
10 АгентБезопасной Нацио
 
17.10.18
14:18
(1) похоже, за чтение СП тоже.
11 1Сергей
 
17.10.18
14:19
(10) черный запрос в данном случае будет медленнее. По крайней мере, не быстрее
12 АгентБезопасной Нацио
 
17.10.18
14:20
(9) не уходи. объясни, пожалуйста, мне, скудоумному, смысл конструкции
пока Доки.ПолучитьДокумент() = 1 Цикл
    ТекДок = Доки.ТекущийДокумент();
    Если ТекДок.Выбран() = 1 Тогда
13 АгентБезопасной Нацио
 
17.10.18
14:21
(11) УстановитьФильтр() тоже критически замедляет работу?
14 1Сергей
 
17.10.18
14:24
(13) это нет
15 АгентБезопасной Нацио
 
17.10.18
14:25
(14) а ВыбратьПоЗначению() запрещено под страхом уголовного наказания?
но меня больше интересует (12). ТКВ...
16 АгентБезопасной Нацио
 
17.10.18
14:32
по идее, задача решается ровно в четыре строчки.
а автор темы сбежал, оставив меня в неведеньи...
17 ADirks
 
17.10.18
14:33
(15) шобы тормозило эффективнее
18 uno-group
 
17.10.18
14:49
В Доки.ВыбратьДокументы(); не мешало бы даты прописать.
хотя бы как то так
Доки.ВыбратьДокументы(ТекДок.ДатаДок-30,ТекДок);
Если вдруг на скл решиш базу перевести конструкции без дат тормозить будут страшно.
19 АгентБезопасной Нацио
 
17.10.18
14:51
(18) вообще-то, лучше позицию.
20 ДНН
 
17.10.18
16:15
(12) Данная конструкция была скопирована из интернета.
Я понимаю ее так:
пока Доки.ПолучитьДокумент() = 1 Цикл - выборка документов
ТекДок = Доки.ТекущийДокумент() - в переменную ТекДок  сохраняется текущий документ выборки
Если ТекДок.Выбран() = 1 Тогда - если текущий документ выбран, то есть это не пустая ссылка, то ... Видимо для того, чтобы при обращении к реквизитам через точку не было ошибки "Элемент не выбран". Допускаю, что при выборки документов через "ВыбратьДокументы()" такии ситуации исключаются, но я в семерке программирую 2 раза в год. Работает и ладно.
21 ДНН
 
17.10.18
16:16
(16) я тебе ответил, теперь ты мне, скудоумному, напиши те самые 4 строчки
22 ДНН
 
17.10.18
16:24
почему при копировании кода из текстового документа в модуль все буквы копируются как знак вопроса?
23 ДНН
 
17.10.18
16:25
*вставляются
24 uno-group
 
17.10.18
16:27
(12) ИМХО откуда-то скопированные условия проверяющие, что в доке автомобиль и т.п. Где в ТекДок мог содержаться еще не записанный документ. Чтобы не менять во всем коде
ТекДок на доки сделали присвоение и код вообще не правили от лишнего. работает да и бог с ним.
25 uno-group
 
17.10.18
16:29
языки при копирование не совподают делай руский в обеих програмах
26 АгентБезопасной Нацио
 
17.10.18
16:36
(20) т.е. думать - запрещено?
откуда в выборке документов возьмется "пустая ссылка"?
----------------
Док=создатьОбъект("Документ.ПЛ");
Док.ОбратныйПорядок(1);
Док.ВыбратьПоЗначению(,СформироватьПозициюДокумента(ТекДок,-1),"Автомобиль",Текдок)
Док.ПолучитьДокумент();

(только надо предварительно создать графу отбора по автомобилю)
27 АгентБезопасной Нацио
 
17.10.18
16:39
может, в третьей строке в последних двух параметрах порядком  ошибся - лень проверять.
ну и первый можно добавить для уменьщнения выборки. зависит от гдубины, на которой точно есть предыдущий документ
28 АгентБезопасной Нацио
 
17.10.18
16:41
(24) "но как, Холмс?"©
29 АгентБезопасной Нацио
 
17.10.18
16:45
+(26) да, конечно же забыл
третью строчку
Док.УстановитьФильтр(Тут_параметы_которые_надо_прочитать_в_СП);
30 uno-group
 
17.10.18
16:57
Док=создатьОбъект("Документ")
Выбрать по значению не работает ко конкретному виду документов и фильтра никакого не надо вы его "ВыбратьПоЗначению" устанавливаете.
31 АгентБезопасной Нацио
 
17.10.18
16:58
(30) Фильтр надо, чтоб только проведенные...
32 Эльниньо
 
18.10.18
11:32
(16) Ну это ты загнул. Пять строчек, не менее
33 Харлампий Дымба
 
18.10.18
13:40
(32) Точно загнул. Три, не более!

Док=СоздатьОбъект("Документ");
Док.УстановитьФильтр(1,0);
Ноль=?(Док.ОбратныйПорядок(1)=0,?(Док.ВыбратьПоЗначению('01.01.1980',СформироватьПозициюДокумента(ДокПЛ.ТекущийДокумент(),-1),"ИмяГрафыОтбораПоАвтобусам",спрАвтомобиль.ТекущийЭлемент())=1,?(Док.ПолучитьДокумент()=1,0,0),0),0);
34 Случайный прохожий
 
18.10.18
13:48
Может правильнее данные по спидометрам поместить в регистр сведений? И не придется каждый раз так извращаться? :)
35 Харлампий Дымба
 
18.10.18
13:58
(34) Уйди мальчик, не мешай. Тут маститые семёрочники собрались. У нас регистра сведений
нет, мы каждый раз извращемся.
+(33) Про спидометр же я забыл - третья строчка такая
пвСпидометрНачальный=?(Док.ОбратныйПорядок(1)=0,?(Док.ВыбратьПоЗначению('01.01.1980',СформироватьПозициюДокумента(ДокПЛ.ТекущийДокумент(),-1),"ИмяГрафыОтбораПоАвтобусам",спрАвтомобиль.ТекущийЭлемент())=1,?(Док.ПолучитьДокумент()=1,Док.СпидометрВозвращения,0),0),0);
36 Дмитрий
 
18.10.18
14:04
(35)  В периодический реквизит можно
37 АгентБезопасной Нацио
 
18.10.18
14:55
(35)"тоже вариант!"©ёжик :-)
38 Базис
 
naïve
18.10.18
15:45
(36) Не надо без крайней необходимости использовать в 77 периодику. А вот регистр "пробег", в нём отбор по автобусу - будет правильно.
39 Харлампий Дымба
 
18.10.18
16:31
(38) Ну, скажем компонента "Оперативный учет" не у всех есть. Может у ТС автобусы к зарплате прикручены или к бухгалтерии.
В случае периодического реквизита:
1 строка в модуле проведения (УстановитьРеквизитСправочника(СпрАвтомобиль.ТекущийЭлемент(),"ЗначениеОдометра",ТекущееЗначениеОдометра)), у нас же всё-таки одометр, верно?
1 строка для получения значения (СпрАвтомобиль.ЗначениеОдометра.Получить(ТекДок));
А с регистрами что-то как-то ну совсем не очень...
40 Эльниньо
 
18.10.18
17:53
(35) "У нас регистра сведений нет...
Делов то. Создай Справочник.РегистрСведений и наслаждайся
41 Kigo_Kigo
 
18.10.18
19:01
(39) Ога ога, и 1сКонст будет пухнуть и пухнуть, потом переодику чистить
(38) только по идее это будет тоже не закрывающийся регистр
Имхо - оптимально- справочник
42 Харлампий Дымба
 
18.10.18
22:54
Ребят вы о чём?!
Чем отбор по справочнику будет отличаться от первоначального перебора документов у ТС в (0)? Как без перебора и периодических реквизитов получить из справочника значение по предпоследнему документу, зная только позицию последнего? Нет, я могу это сделать - но это будет тоже самое, что уже есть с документами.
Даже хуже, потому что как сделать вот это:

Док.ВыбратьПоЗначению(,СформироватьПозициюДокумента(ДокПЛ.ТекущийДокумент(),-1),"ИмяГрафыОтбораПоАвтобусам",спрАвтомобиль.ТекущийЭлемент())?
Сделать реквизит "Автобус" с галкой "Сортировка" -  можно сделать ВыбратьЭлементыПоРеквизиту() - а дальше? Как спозиционироваться на нужном документе не нарушив уже установленную выборку? Только перебором.
Сделать реквизит "Документ" - с галкой "Сортировка" - теперь можно спозиционироваться на нужном документе. А как по нему найти предыдущий по этому же автобусу? Опять перебором. А запросом по всему справочнику - ещё дольше, чем перебором, проверено.
И при этом появляется ненужная сущность, которая так и просится под бритву Оккама.

Сколько автобусов должно быть у автора, чтобы один периодический реквизит, даже записываемый каждый день, серьёзно загрузил 1sconst? Если люди годами работают на полутиповом ТиСе с кучей товарных позиций и типов цен к ним? И зачем вообще тогда нужны периодические реквизиты, если ими не пользоваться?

Про регистр я вообще молчу. Если регистр остатков - надо делать две записи сразу, чтобы закрывался. Как получить значение на документ? Если через Рег.Остаток(), тогда надо при проведении документа рассчитывать регистр и писать не текущее значение одометра, а изменение. И делать последовательность и следить за границей этой последовательности, потому как впихнутый между другими документ (или распроведенный) изменит текущий остаток - получится ерунда.
Если оборотный - как тогда получать значение? А если несколько поездок в день, какая периодичность регистра?

Ещё можно прямым запросом...
Или на 8 перевести фирму...

А то 3 строчки как-то сложно, а доли секунды как-то долго.
43 АгентБезопасной Нацио
 
19.10.18
07:25
(42) с точки зрения индексов - лучше либо графа отбора, либо  оборотный регистр с "быстрыми движениями". с точки зрения отсутсвия излишеств - эмуляция регистра сведений справочником.
скалярный прямой запрос вообще напрашивается. а можно просто вышеупомянутые "строчки". три их или пять - уже не столь важно...
44 Харлампий Дымба
 
19.10.18
22:05
(43) Просто, для своего развития. Допустим, регистр сведений справочником я сделал. Автомобиль, документ (позиция, дата), значение. Ну и любые индексы к нему. Как быстро получить значение предыдущего документа по этому автомобилю?
45 palsergeich
 
19.10.18
22:34
(44) Написать запрос.
Поля запроса и условия должны покрываться индексом
46 Харлампий Дымба
 
19.10.18
23:19
(45)
1) Зачем тогда городить справочник, если запрос я могу написать сразу к документу "Документ.ПЛАвтобуса"?
2) Запрос, перебирающий все элементы справочника, вместо "открыл выборку, получил предыдущий"? Где ускорение, какой смысл? Какие индексы помогут моему запросу? Мы точно про 7ку говорим, бо в 8ке регистр сведений уже есть и там можно и нужно использовать уже готовое?
47 palsergeich
 
20.10.18
00:44
(46) угу признаю, неверно понял задачу в (44)
48 АгентБезопасной Нацио
 
22.10.18
08:38
(44) прямым запросом :-)
(46) объем меньше, следовательно, накладные расходы меньше.