Имя: Пароль:
1C
1C 7.7
v7: Как ускорить запрос в 1С 7.7
0 Косяк
 
24.03.16
08:40
Есть задача: найти последний по дате приходный документ, в котором есть конкретный материал. База довольно большая и за несколько лет.

Делаю соответствующий запрос. Обхожу этот запрос в нужном мне порядке. а именно, - в обратном порядке. Обойти то я его обойду, но это когда он уже сформирован, а формироваться он может долго.

Сам запрос выполняется по всем годам в прямом порядке: сначала год 2000, затем 2001 и т.д.

Неужели нет способа ускорить?

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

Как?

Процедура НайтиПоследний()

ВыбратьСтроки();       
Пока ПолучитьСтроку()=1 Цикл
    Если ПустаяСтрока(ОсновнойМатериал)<>1 Тогда
        ОснМатериал = ОсновнойМатериал;
        //Сообщить("ОсновнойМатериал="+ОсновнойМатериал);
    КонецЕсли;    
КонецЦикла;    
    
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса =  "
|Период с '01.01.2000' по '31.12.2016';
|ОбрабатыватьДокументы Проведенные;
|ПоступлениеМатериалов = Документ.ПоступлениеМатериалов.ТекущийДокумент;    
|Поставщик = Документ.ПоступлениеМатериалов.Контрагент.Наименование;
|ДатаДокумента = Документ.ПоступлениеМатериалов.ДатаДок;      
|ДатаНомерСчФактуры = Документ.ПоступлениеМатериалов.ДатаНомерСчетаФактуры;                                                  
|ОсновнойМатериал  = Документ.ПоступлениеМатериалов.Материал;    
|Группировка ПоступлениеМатериалов упорядочить по ПоступлениеМатериалов.ДатаДок;
|Условие(ОсновнойМатериал.Код = ОснМатериал.Код);
|"
;
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
     Возврат;
КонецЕсли;                                            

Пока Запрос.Группировка("ПоступлениеМатериалов", -1) = 1 Цикл   // -1 - Обход результатов запроса в обратном порядке      
    Сообщить("Запрос.ДатаДокумента=" + Запрос.ДатаДокумента + "  Запрос.ДатаНомерСчФактуры="+Запрос.ДатаНомерСчФактуры);

КонецЦикла;

КонецПроцедуры
7 1Сергей
 
24.03.16
08:55
(2) +1
А также есть смысл использовать запрос к регистру
8 Lazy Stranger
 
24.03.16
09:01
если это оперучет - я бы по регистру искал, что-то вроде
рег = СоздатьОбъект("Регистр.ОстаткиТМЦ");
рег.УстановитьЗначениеФильтра("Номенклатура",ОснМатериал)
рег.ОбратныйПорядок(1);
рег.ВыбратьДвидения();
Пока рег.ПолучитьДвижение()=1 цикл
Если рег.ТекущийДокумент().Вид()="ПоступлениеМатериалов" тогда
ИскомыйДокумент = рег.ТекущийДокумент();
прервать;
КонецЕсли;
КонецЦикла;
и проверить наличие галки "отбор движений" на соответствующем измерении регистра
9 Mikeware
 
24.03.16
09:04
(8) а лучше все-таки (3)
10 Lazy Stranger
 
24.03.16
09:06
(9) лучше, но сложнее на порядок - разбираться с отдельной технологией и приделывать ВК к базе
11 Mikeware
 
24.03.16
09:07
(10) у него база вроде даже сиквельная.
12 Lazy Stranger
 
24.03.16
09:15
(11) если чел в обычно запросе вместо ОсновнойМатериал= ОснМатериал пишет ОсновнойМатериал.Код = ОснМатериал.Код, страшно представить что в прямых запросах будет (впрочем я тоже их писать не умею, хотя видоизменять готовые доводилось, есть у меня клиент, где предшественник писал отчеты прямыми запросами - штука могучая, конечно)
13 Косяк
 
24.03.16
09:25
(2)А как по-вашему будет выглядеть вариант с выборкой?
14 Ёпрст
 
24.03.16
09:29
(0) прямой запрос.
А так, в (0), вот за этот код
|Условие(ОсновнойМатериал.Код = ОснМатериал.Код);
нужно стальной линейкой по пальчикам бить
15 trad
 
24.03.16
09:41
(14) ребром линейки или гранью?
16 Злопчинский
 
24.03.16
09:44
(15) а можно я еще фофана отвешу?
17 Mikeware
 
24.03.16
09:53
(12) ну дык! Ник-то у него говорящий...
18 Масянька
 
24.03.16
09:55
Если бы вы работали учителями/преподавателями - давно бы уже сидели... За насилие над учащимися... :)
19 kobzon2
 
24.03.16
09:57
(18) Не дай бог таких в инструктора по вождению))
20 Косяк
 
24.03.16
09:59
(14)Чем ненормален код?
21 Mikeware
 
24.03.16
09:59
(18) я - работал :-)
Ученики через 15 лет спасибо говорили...
22 Mikeware
 
24.03.16
10:00
(20) анахуа он?
23 Косяк
 
24.03.16
10:02
(22)Вы не понимете зачем нужен запрос
24 Масянька
 
24.03.16
10:03
(23) Блин... Прострелить коленку...
25 Злопчинский
 
24.03.16
10:03
(21) аналогично, хотя я "учил" меньше. Но постоянно ругаюсь сейчас на всяких ларечников-клюшечников - стучаться за консультациями... ниче, терпят, пасибу говорят, денежку перечисляют.

Если не мы, то - кто?
26 Ёпрст
 
24.03.16
10:03
(20) ну как тебе сказать, например в sql базе выполняется в разы медленнее, если написать по-человечьи
27 trad
 
24.03.16
10:03
(18) у нас в школе, когда я учился, математичка была - старушка старой закалки, могла и линейкой по башке и мелком метко швырнуть.
Одна из самых уважаемых была, и уважали как хорошего учителя, а не из-за страха
28 Mikeware
 
24.03.16
10:04
(24) одну?
29 Злопчинский
 
24.03.16
10:04
(23) если работы разовые/редко - то забить на быстройдействие.
30 Mikeware
 
24.03.16
10:04
(23) я не понимаю, зачем сравнивать по коду.
31 Масянька
 
24.03.16
10:06
(27) Тогда - времена были другие. Учитель был авторитетом. А сегодня? Ученик откровенно саботирует, да еще и права качает...
32 Ёпрст
 
24.03.16
10:09
У нас многие учителя могли запросто линеечкой по пальчикам
33 Mikeware
 
24.03.16
10:09
(31) авторитет не зависит от "времени". авторитет зависит от человека.
34 Mikeware
 
24.03.16
10:10
остается вспомнить анекдот про бегемотиков...
35 Ёпрст
 
24.03.16
10:10
Вот блин, батка рассказывал, раньше вообще на горох ставили, от наука то где была!
36 Ёпрст
 
24.03.16
10:11
(34) в нашей версии про летающих крокодильчиков.
37 Злопчинский
 
24.03.16
10:11
(35) ты ишшо маладой, мне так в детстве поприходилось на горохе в углу постоять...
38 kobzon2
 
24.03.16
10:12
(23) Убери это условие |Условие(ОсновнойМатериал.Код = ОснМатериал.Код);
И добавь его в обход группировки.
Пока Запрос.Группировка("ПоступлениеМатериалов", -1) = 1 Цикл  // -1 - Обход результатов запроса в обратном порядке      
Если Запрос.ОсновнойМатериал = ОснМатериал Тогда
    Сообщить("Запрос.ДатаДокумента=" + Запрос.ДатаДокумента + "  Запрос.ДатаНомерСчФактуры="+Запрос.ДатаНомерСчФактуры);
Прервать;
КонецЕсли;
КонецЦикла;

Разве так не лучше?)
39 Масянька
 
24.03.16
10:12
(33) Не прав... Сегодня даже просто накричать - чревато.
Не было раньше такого. Не было.
40 ДенисЧ
 
24.03.16
10:13
(37) Подай на них в суд, как виновников детской застарелой психической травмы
41 Mikeware
 
24.03.16
10:14
гыыы! в (38) - второй!
42 Ёпрст
 
24.03.16
10:14
(39) не было чего ?
43 Mikeware
 
24.03.16
10:15
(42) сотовых телефонов.
44 Ёпрст
 
24.03.16
10:15
(37) каюсь, не застал.
45 Mikeware
 
24.03.16
10:16
(44) исправляйся. сам. если  накосячишь - так сразу...
46 Косяк
 
24.03.16
10:35
(38) Проверил. Абсолютно никакой разницы.
47 Ёпрст
 
24.03.16
10:39
Если делать штатно, то добавить графу отбора и ВыбратьПоЗначению, будет не быстро, а очень быстро. Можно еще и ускорить, ограничив через ИспользоватьЖурнал
48 Mikeware
 
24.03.16
10:41
(47) слушай, а 1sqlite только на чтение работает, чтоль ?
49 Mikeware
 
24.03.16
10:41
(47) если ему разово надо - то добавление графы будет дольше..
50 Ёпрст
 
24.03.16
10:42
(48) яяя, инсерт/делете там только с родной базой можно
51 MishaD
 
24.03.16
10:50
я бы для начала попробовал бы еще альтернативные варианты. Выборку и Бухитоги.
52 Косяк
 
24.03.16
10:56
как?
53 Mikeware
 
24.03.16
11:00
(52) база файловая или сиквельная?
54 Косяк
 
24.03.16
11:13
(53) SQL
55 kobzon2
 
24.03.16
11:25
(52) Если запрос работает в прямом порядке, может тогда ну его нах? Делать через выборку документов в обратном порядке.
56 Косяк
 
24.03.16
11:35
>>Делать через выборку документов в обратном порядке.

Тема создана для этого!
57 Косяк
 
24.03.16
11:35
Как выбрать документы в обратном порядке???!!!
58 MishaD
 
24.03.16
11:39
Давно бы заглянул в синтакс помошник
ОбратныйПорядок(<?>);
Синтаксис:
ОбратныйПорядок(<Режим>)
Назначение:
Установить порядок выборки документов во времени.
Возвращает значение порядка выборки до вызова:   1 - выборка документов в порядке убывания даты и времени;  0 - в порядке возрастания.
Параметры:
<Режим> -  необязательный параметр. Число: 1 - выбирать документы в порядке убывания даты и времени;   0 - выбирать документы в порядке возрастания даты и времени. Если параметр опущен, то метод просто возвращает текущее значение порядка выборки документов.
Замечание:
Метод можно использовать как процедуру и как функцию.
Метод  можно использовать только для объектов, созданных функцией СоздатьОбъект.
59 Lazy Stranger
 
24.03.16
11:42
(57) регистры остатков каких-нибудь двигает этот документ?
если да - чем вариант из (8) не подходит?
60 kobzon2
 
24.03.16
11:43
Док = СоздатьОбъект("Документ.ПоступлениеМатериалов");
    Док.ОбратныйПорядок(1);
    Пока Док.ПолучитьДокумент() = 1 Цикл;
        Если Док.ОсновнойМатериал = ОснМатериал Тогда
    Сообщить("Запрос.ДатаДокумента=" + Запрос.ДатаДокумента + "  Запрос.ДатаНомерСчФактуры="+Запрос.ДатаНомерСчФактуры);
Прервать;
        КонецЕсли;    
    КонецЦикла;
61 kobzon2
 
24.03.16
11:45
Забыл Док.ВыбратьДокументы(Дата1,Дата2); (60)
62 Mikeware
 
24.03.16
11:46
(61) ты много чего забыл. а скорее всего даже не знал, а еще и забыл...
63 Lazy Stranger
 
24.03.16
11:47
(60) подозреваю что материал там в табл. части - перебирать все строки всех документов - ещё больший изврат чем в (0)
64 Mikeware
 
24.03.16
11:48
(57)
Загрузи 1cpp.dll ,  и выполни следующее:

рс=СоздатьОбъект("ODBCRecordset");
ТекстЗапроса="
|SELECT TOP 1 Журнал.IDDOC [Документ $Документ.ПоступлениеТМЦ]
|FROM _1SJOURN AS Журнал With (NOLOCK)
|    INNER JOIN $ДокументСтроки.ПоступлениеТМЦ AS ПоступлениеТМЦСтроки With (NOLOCK) ON Журнал.IDDOC = ПоступлениеТМЦСтроки.IDDOC
|WHERE ($ПоступлениеТМЦСтроки.Номенклатура = :ВыбНоменклатура)
|    AND ((Журнал.CLOSED & 1) = 1)
|ORDER BY Журнал.DATE_TIME_IDDOC DESC
|";
рс.УстановитьТекстовыйПараметр("ВыбНоменклатура",ВыбНоменклатура);

(вместо "ПоступлениеТМЦ" поставь название своего дока, вместо Номенклатура - название твоего поля)
65 kobzon2
 
24.03.16
11:49
(63) Если в табличной то да, геморр..
66 Mikeware
 
24.03.16
11:49
Не скопировалась еще одна сточка: ДокПоступление=рс.ВыполнитьСкалярный(ТекстЗапроса);
67 kobzon2
 
24.03.16
11:51
(62) Не умничай. За 62 поста, сколько решений предложил ты?
68 Mikeware
 
24.03.16
11:54
(67) лучше молчать, чем нести куйню, как ты.
я могу сделать это добрым десятком методов. но самый правильный был предложен в (3)
69 ДенисЧ
 
24.03.16
11:56
(68) Я всегда правильные методы подсказываю ))
Правда, не все это ценят...
70 MishaD
 
24.03.16
11:57
Насчет SQL не скажу, но на файловой выборка вполне могла оказаться быстрей.
71 kobzon2
 
24.03.16
11:58
(68) Это ты все посты в этой теме нёс куйню, перечитай. И не затыкай меня!
72 Mikeware
 
24.03.16
12:05
(70) если графа используется - то да. Там тогда вообще шесть строк....
73 Mikeware
 
24.03.16
12:05
(71) уймись, дерево....
74 Косяк
 
24.03.16
12:08
(68)Мальчики, не ссорьтесь.
75 kobzon2
 
24.03.16
12:15
(73) Ты не у себя на кухне, иди проспись.
76 Косяк
 
24.03.16
12:24
(64) "Загрузи 1cpp.dll" - это как?
77 Mikeware
 
24.03.16
12:26
78 Mikeware
 
24.03.16
12:27
(75) у меня на кухне дерева нет. ДСП есть. ты из опилок?
79 Косяк
 
24.03.16
12:48
(64)
рс=СоздатьОбъект("ODBCRecordset");
{Документ.Обоснование1.Форма.Модуль(94)}: Неудачная попытка создания объекта (ODBCRecordset)

1CPP.DLL лежит в папке 1С BIN
80 Mikeware
 
24.03.16
12:52
(79)  Если ЗагрузитьВнешнююКомпоненту("1CPP.dll") = 0 Тогда Предупреждение("Неудачная попытка загрузить 1CPP.dll"); СтатусВозврата(0); Возврат; КонецЕсли;
81 Ёпрст
 
24.03.16
12:52
(79) загрузитьвнешнююкомпоненту(1cpp.dll); воткни в поделку свою, примерно так:

Попытка
   рс=СоздатьОбъект("ODBCRecordset");
Исключение
  Если ЗагрузитьВнешнююКомпоненту("1cpp.dll") =0 Тогда
    Предупреждение ("Пнх, Альфредо!");
    Возврат;
  КонецЕсли;
   рс=СоздатьОбъект("ODBCRecordset");
КонецПопытки

примерно
82 Косяк
 
24.03.16
13:18
Попытка
  RS=СоздатьОбъект("ODBCRecordset");
Исключение        
Если ЗагрузитьВнешнююКомпоненту("1cpp.dll") =0 Тогда  Предупреждение ("Не удалось загрузить 1cpp.dll ");
    Возврат;
КонецЕсли;
КонецПопытки ;

ТекстЗапроса="
|SELECT TOP 1 Журнал.IDDOC [Документ $Документ.ПоступлениеМатериалов]
|FROM _1SJOURN AS Журнал With (NOLOCK)
|    INNER JOIN $ДокументСтроки.ПоступлениеМатериалов AS ПоступлениеМатериалов With (NOLOCK) ON Журнал.IDDOC = ПоступлениеМатериаловСтроки.IDDOC
|WHERE ($ПоступлениеМатериаловСтроки.Материал = :Материал)
|    AND ((Журнал.CLOSED & 1) = 1)
|ORDER BY Журнал.DATE_TIME_IDDOC DESC
|";
RS.УстановитьТекстовыйПараметр("Материал",ОснМатериал);

ТЗвыборка = СоздатьОбъект("ТаблицаЗначений");
ТЗвыборка = RS.ВыполнитьИнструкцию(ТекстЗапроса);
RS = "";

ТЗВыборка.ВыбратьСтроки();

Пока ТЗВыборка.ПолучитьСтроку()=1 Цикл
  Материал = ТЗВыборка.Материал;
  Сообщить("Материал="+Материал);
КонецЦикла;

КонецПроцедуры    

Что то не хочет работать, не пойму почему..

RS.УстановитьТекстовыйПараметр("Материал",ОснМатериал);
{Документ.Обоснование1.Форма.Модуль(110)}: Значение не представляет агрегатный объект (УстановитьТекстовыйПараметр)
83 Mikeware
 
24.03.16
13:20
после загрузки компонениы еще раз создай одбсрекордсет. ты ж его не создал - вывалился по исключению....
84 Ёпрст
 
24.03.16
13:26
(83) ну, не приучен тс к копипасту
:)
85 Ёпрст
 
24.03.16
13:27
да и..текст запроса не верный.
86 Косяк
 
24.03.16
13:28
(85)что не так
87 Ёпрст
 
24.03.16
13:29
(86)
>>>ПоступлениеМатериаловСтроки.IDDOC

нет такого алияса ПоступлениеМатериаловСтроки
есть ПоступлениеМатериалов
если че
ну и дальше по тексту исправить
88 Косяк
 
24.03.16
14:18
Процедура НайтиПоследний()

ВыбратьСтроки();       
Пока ПолучитьСтроку()=1 Цикл
    Если ПустаяСтрока(ОсновнойМатериал)<>1 Тогда
        ОснМатериал = ОсновнойМатериал;
    КонецЕсли;    
КонецЦикла;    
    
Попытка
  RS=СоздатьОбъект("ODBCRecordset");
Исключение        
Если ЗагрузитьВнешнююКомпоненту("1cpp.dll") =0 Тогда  Предупреждение ("Не удалось загрузить 1cpp.dll ");
    Возврат;
КонецЕсли;
КонецПопытки ;                


DataBase = СоздатьОбъект("ODBCDatabase");
DataBase.Attach1C();

RS=СоздатьОбъект("ODBCRecordset");                    
RS.SetDatabase(DataBase);

ТекстЗапроса="
|SELECT TOP 10 Журнал.IDDOC [Документ $Документ.ПоступлениеМатериалов]
|FROM _1SJOURN AS Журнал With (NOLOCK)
|    INNER JOIN $ДокументСтроки.ПоступлениеМатериалов AS ПоступлениеМатериалов With (NOLOCK) ON Журнал.IDDOC = ПоступлениеМатериалов.IDDOC
|WHERE ($ПоступлениеМатериалов.Материал = :Материал)
|    AND ((Журнал.CLOSED & 1) = 1)
|ORDER BY Журнал.DATE_TIME_IDDOC DESC
|";
RS.УстановитьТекстовыйПараметр("Материал",ОснМатериал);

ТЗ = СоздатьОбъект("ТаблицаЗначений");
ТЗ = RS.ВыполнитьИнструкцию(ТекстЗапроса);

ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку()=1 Цикл
  Материал = ТЗ.Материал;
  Сообщить("Материал="+Материал);
КонецЦикла;

КонецПроцедуры    


Не знаю что надо исправить, не работает..
89 ДенисЧ
 
24.03.16
14:22
а что именно не работает?
90 Косяк
 
24.03.16
14:37
ТЗ.ВыбратьСтроки();
{Документ.Обоснование1.Форма.Модуль(124)}: Значение не представляет агрегатный объект (ВыбратьСтроки)
91 Mikeware
 
24.03.16
14:38
(88) вместо
----------
DataBase = СоздатьОбъект("ODBCDatabase");
DataBase.Attach1C();

RS=СоздатьОбъект("ODBCRecordset");                    
RS.SetDatabase(DataBase);
---------
оставить только
---------
RS=СоздатьОбъект("ODBCRecordset");                    
----------
92 Mikeware
 
24.03.16
14:39
ну и
  Материал = ТЗ.Материал;
естественно, даст ошибку...
93 Mikeware
 
24.03.16
14:40
Кстати, в ПоступлениииМатериалов Материал - какого вида?
94 Косяк
 
24.03.16
14:42
(93)из справочника Материалы
95 Ёпрст
 
24.03.16
14:42
и типа ? мало ли, он там как <Справочник>
96 Косяк
 
24.03.16
14:47
Если оставлю только RS=СоздатьОбъект("ODBCRecordset"); то получаю ошибку

ТЗ = RS.ВыполнитьИнструкцию(ТекстЗапроса);
{Документ.Обоснование1.Форма.Модуль(122)}: База данных не установлена
97 Ёпрст
 
24.03.16
14:53
(96) 1cpp какой версии хоть ?
98 Масянька
 
24.03.16
14:57
Фига себе...
До сотки дотянули...

А сделал бы выборку - уже давно другую задачу решал бы...
Комсомольцы, блин...
99 Ёпрст
 
24.03.16
15:20
(98) он не сделал бы.
100 Mikeware
 
24.03.16
15:23
(98) если б он мог бы сделать - давно б сделал...
101 Lazy Stranger
 
24.03.16
15:25
(99, 100) прямым запросом он и к 1000-му посту не сделает, похоже я в (10) правильно оценил уровень сложности
102 Mikeware
 
24.03.16
15:38
(101) а каким - по твоему мнению - он способен?
1) тупой перебор доков и строк
2) перебор по графе
3) запрос/бухзапрос
4) перебор регистра
103 Ёпрст
 
24.03.16
15:50
Чего-то автор по-ходу курнул, раз не отвечает, надо ж хоть как-то нику соответствовать
104 Mikeware
 
24.03.16
15:56
(103) если б курнул - рассказывал бы долго и витиевато...
Хотя, конечно, у на кого как подействует...
------------
Cтоит на холме Мальчиш-кибальчиш и кричит:
- Измена, измена, измена!!!
Под холмом сидит Мальчиш-плохиш, жрет варенье, заедает печеньем  и говорит:
- Странная шука эта конопля-  кого на измену пробивает,а кого на хавчик...
105 Duke1C
 
24.03.16
22:50
(96) Ты для начала бы на (4), (6) ответил/попробовал...
Сдается  мне, что рано тебе пока прямые запросы по шаблонам править
106 Масянька
 
25.03.16
08:53
(104) Интересно, а "Малыш и Карлсон" - это шведский вариант?