Имя: Пароль:
1C
1C 7.7
v7: Помогите с запросом sql 1с++
0 failures
 
29.03.12
06:25
Я начинающий в прямых запросах к SQL. Столкнулся с одной проблемой. Есть примерно такой код:

тз.ВыбратьСтроки();
Пока тз.ПолучитьСтроку()=1 Цикл
   ДокОснование=тз.ДокОснование;
   Пока ПустоеЗначение(докОснование.ДокОснование)=0 Цикл
       докОснование=ДокОснование.ДокОснование;
   КонецЦикла;
   тз.ДокОснование=ДокОснование;
КонецЦикла;

То есть ищется первый документ в структуре подчиненности (все документы одного типа, поле "докоснование" - поле документа, а не журнала). Можно ли создать прямой запрос через 1с++, чтобы по списку документов получить соответствующие документы, которые первые в структуре подчиненности?
1 Спорт
 
29.03.12
06:37
Да, можно конечно. Предварительно подготовить надо список значенйи СписокЗаявок, уложить его и конечно требуется знать вид документа. Запрос примерно такой:
ТекстЗапроса = "
   |SELECT Заявка.IDDOC [Ссылка $Документ.Заявка]
   |    ,(select top 1 right(cr.child_date_time_iddoc,9) from _1scrdoc cr (nolock)
   |    where cr.mdid = 0 and cr.parentval = 'O1'+ $ВидДокумента36.Заявка + Заявка.IDDOC
   |    order by cr.child_date_time_iddoc) Заявка
   |FROM $Документ.Заявка AS Заявка
   |    INNER JOIN _1SJOURN AS Журнал ON Заявка.IDDOC = Журнал.IDDOC
   |WHERE (Заявка.IDDOC IN (SELECT val FROM #СписокЗаявок))
   |";
2 Спорт
 
29.03.12
06:54
Я упрощенный запрос тебе выложил, выкинул ненужное и недосмотрел, что внутренне соединение с журналом в данном случае уже не требуется, ты же документы будешь в списке значений подсовывать, т.е. запрос упрощается до:
ТекстЗапроса = "
   |SELECT Заявка.IDDOC [Ссылка $Документ.Заявка]
   |    ,(select top 1 right(cr.child_date_time_iddoc,9) from _1scrdoc cr (nolock)
   |    where cr.mdid = 0 and cr.parentval = 'O1'+ $ВидДокумента36.Заявка + Заявка.IDDOC
   |    order by cr.child_date_time_iddoc) ПервыйПодчиненныйДокумент
   |FROM $Документ.Заявка AS Заявка
   |WHERE (Заявка.IDDOC IN (SELECT val FROM #СписокЗаявок))
   |";
3 failures
 
29.03.12
07:13
(2) ПервыйПодчиненныйДокумент возвращается в формате непонятном 1с (типа WHVG)
4 Спорт
 
29.03.12
07:18
Можно в виде документа вернуть, тогда вот так:
ТекстЗапроса = "
   |SELECT Заявка.IDDOC [Ссылка $Документ.Заявка]
   |    ,(select top 1 right(cr.child_date_time_iddoc,9) from _1scrdoc cr (nolock)
   |    where cr.mdid = 0 and cr.parentval = 'O1'+ $ВидДокумента36.Заявка + Заявка.IDDOC
   |    order by cr.child_date_time_iddoc) [ПервыйПодчиненныйДокумент $Документ]
   |FROM $Документ.Заявка AS Заявка
   |WHERE (Заявка.IDDOC IN (SELECT val FROM #СписокЗаявок))
   |";
5 failures
 
29.03.12
07:25
(4) Заработало, но видимо я неправильно объяснил. Твой запрос находит последний подчиненный документ, а мне надо находить "корень подчинения" у каждого документа в списке
6 Mikeware
 
29.03.12
07:45
Два варианта: либо рекурсивная функция (правда, насколько помню, там ограничение по вложенности вызовов - 32), либо запрос с ветвлением, где число ветвей - это потенциальная максимальная вложенность
7 Mikeware
 
29.03.12
07:46
(1) ему надо первый по структуре подчиненности ("корневой документ"), а не "первый [из родителей] по времени".
8 dk
 
29.03.12
07:55
(7) просто код в (0) не возвращает корень, а просто на 1 уровень вверх поднимается
9 orefkov
 
29.03.12
07:55
Для дбф можно посмотреть http://snegopat.ru/downloads/1sqlite/doc_graph.zip
Но в общем случае - корня может и не быть - док может быть подчинен нескольким документам  либо есть зацикливание в подчиненности. То есть в общем случае - структура подчиненности не дерево, а граф.
Для sql ищи на форуме 1С++ мою же "граф подчиненности документов".
10 dk
 
29.03.12
07:59
плюс нет защиты от зацикливания
11 dk
 
29.03.12
08:12
имхо не самая удобная задачка для 1с++
т.е. решить мона, но вопрос в целесообразности (выигрыш в скорости и трудность реалицации)
12 failures
 
29.03.12
08:13
(8) Поднимается на один уровень вверх по циклу, по этому на выходе цикла корень документа.
(9) (10) Защита от зацикливания не нужна, если использовать только один вид документа. Если корня нет, то возвращается текущий документ.
(11) В таблице порядка 17000 строк поиск циклом из (0) проходит около 10 минут.

В общем похоже придется запросом загонять все документы этого типа в таблицу со столбцами ссылка и докоснование и обрабатывать в цикле ее вместо обработки журнала... Но это же не намного быстрее и очень тупо...
13 dk
 
29.03.12
08:24
прогнал про поднятие на 1 уровень - второй цикл не заметил
14 Спорт
 
29.03.12
08:38
(5) Элементарно, Ватсон. Если нужен ПЕРВЫЙ то тогда
order by cr.child_date_time_iddoc DESC
15 failures
 
29.03.12
08:45
(14) Все равно не работает. И ПервыйПодчиненныйДокумент часто имеет вид отличный от исходного.
16 Спорт
 
29.03.12
08:46
Сейчас понял что тебе надо. Ну блин.. Это надо подумать посидеть. Какой порог вложенности?
17 Спорт
 
29.03.12
08:48
Т.е. находим у текущего документа основание, у найденого - его основание, у того - опять основание и т.д. пока не найдем док БЕЗ основания. Он и будет искомым, да?
18 Спорт
 
29.03.12
08:50
На вскидку - можно тупо одним запросом лупануть документов на 10 с CASE WHEN IS NULL.
19 failures
 
29.03.12
08:56
(16) Порог вложенности не известен... Хотя в принципе пользователей не будет интересовать вложенность ранее трех месяцев от даты начала отчета...
20 failures
 
29.03.12
08:56
(17) Да.
21 dk
 
29.03.12
08:57
(18) для этого придумали COALESCE
22 failures
 
29.03.12
09:02
Пока тупое решение такое:

       рс = СоздатьОбъект("ODBCRecordset");
       ТекстЗапроса = "
       |SELECT ЗаявкаПокупателя.IDDOC [Ссылка $Документ.ЗаявкаПокупателя]
       |    , $ЗаявкаПокупателя.ДокОснование [ДокОснование $Документ]
       |FROM $Документ.ЗаявкаПокупателя AS ЗаявкаПокупателя With (NOLOCK)
       |    INNER JOIN _1SJOURN AS Журнал With (NOLOCK) ON ЗаявкаПокупателя.IDDOC = Журнал.IDDOC
       |WHERE (Cast(Left(Журнал.DATE_TIME_IDDOC, 8) AS datetime) <= :ДатаКон)
       |    AND (Cast(Left(Журнал.DATE_TIME_IDDOC, 8) AS datetime) >= :ДатаНач)
       |GROUP BY ЗаявкаПокупателя.IDDOC
       |    , $ЗаявкаПокупателя.ДокОснование
       |";
       рс.УстановитьТекстовыйПараметр("ДатаКон", ДатаКонца);
       рс.УстановитьТекстовыйПараметр("ДатаНач", ДатаНачала-100);
       тз = рс.ВыполнитьИнструкцию(ТекстЗапроса);
       Для Ик=1 По Итог.КоличествоСтрок() Цикл
           Состояние("Ищем заявки... "+Ик+"/"+Итог.КоличествоСтрок());
           ТекЗаявка=Итог.ПолучитьЗначение(Ик,"Заявка");
           Пока СокрЛП(ТекЗаявка.ДокОснование)<>"" Цикл
               стр=0;
               Если тз.НайтиЗначение(ТекЗаявка,стр,"Ссылка")=1 Тогда
                   
                   тз.ПолучитьСтрокуПоНомеру(стр);
                   ТекЗаявка=тз.ДокОснование;
               Иначе
                   Прервать;
               КонецЕсли;
           КонецЦикла;
           
           Итог.УстановитьЗначение(Ик,"Заявка",ТекЗаявка);
       КонецЦикла;

Поиск делается быстрее, но все равно все тупо и медленно...
23 dk
 
29.03.12
09:08
(22)
1. WHERE Журнал.DATE_TIME_IDDOC between :ДатаНач AND :ДатаКон~
2. Группировку убрать
24 Спорт
 
29.03.12
09:12
(22) Думаю самое оптимальное решение в данной ситуации, даже с COALESCE на 10 оснований получается мегавесёлый запрос
25 failures
 
29.03.12
09:14
(23) Это не принципиально, так как +(24) 99% времени уходит на вложенный цикл поиска. И именно это и нуждается в оптимизации...
26 Спорт
 
29.03.12
09:15
(25) ИндексированнаяТаблица используй, там скорость в разы выше при поиске.
27 Ёпрст
 
гуру
29.03.12
09:16
(9) 26 версию не поправишь ?
Та что в новой сборке - частый вылет на простых запросах + если задан период по индексу, типа idx_date_tame_iddoc - не учитывается конечная дата, т.е в between как бы < стоит ..а не <=
28 Спорт
 
29.03.12
09:17
(0) Если проблема очень насущная, то как вариант можно сведения о подчиненности складывать в спец. справочник при записи документа.
29 orefkov
 
29.03.12
09:17
(12)
Как это защита от зацикливания не нужна?
У док2 основанием док1, а у того - док2.
До морковинова заговенья будет цикл крутить.
Надеяться на то, что такой ситуации быть не может - самонадеяно.
30 orefkov
 
29.03.12
09:18
(27)
Постараюсь посмотреть. Времени мало со снегопатом.
31 Ёпрст
 
гуру
29.03.12
09:20
(30) продажи идут ?
Надо бы тоже перечислить копейку..
32 failures
 
29.03.12
09:26
(29) Такого быть не может. В самой конфиге много чего написано, чтоб документы по этому виду не могли зацикливаться по подчинению. Новый док всегда ставится после ТА, поле ДокОснование выставляется программно, по этому подчиненный документ всегда по времени после родителя. Зацикливание возможно, если включать в поиск документы других видов.
33 Ёпрст
 
гуру
29.03.12
09:27
(32) :)))))))))))))
Ну и бред... еще и ТА сюда приплёл
34 orefkov
 
29.03.12
09:29
(32)
Подчиненность никак не связана ни с размещением на оси времени, ни с видами документов.
35 Спорт
 
29.03.12
09:32
(31) Снегопат за копейку? Это что акция какая-то? Тоже купил бы, за копейку-то. "что скажет купечество?" ©
36 Ёпрст
 
гуру
29.03.12
09:33
(34) если будешь всё же смотреть 36 релиз - падает даже на простейшем запросе к справочнику + like в условии
37 Ёпрст
 
гуру
29.03.12
09:33
26 т.е
38 Он
 
29.03.12
09:40
Дабы не плодить ветки.

Скуль2005 локально. Жрёт память по-чёрному. После завершения сеанса 1С взад не отдаёт, гад.
Чё нужно ему сказать, чтобы отдал?
39 Спорт
 
29.03.12
09:42
(38) "Дабы не плодить... " Иди отсюда в свою ветку со скулем, не вишь, тут с прямыми запросами разбираются люди.
40 failures
 
29.03.12
09:43
(33) (34) время и вид документа в данном случае являются защитой от зацикливания.
41 orefkov
 
29.03.12
09:44
(36)
Так это я вроде поправил. Не пробовал перекачать?
(35)
Акций нет. Ёпрст снегопат получил даром как тестер. Но совесть видимо его все равно гложет :)
42 Он
 
29.03.12
09:45
(39) Я тоже начал прямые изучать.
Вот бы какой-нить Sql.als.
43 Спорт
 
29.03.12
09:46
Иди-иди давай, начал он изучать.
44 Спорт
 
29.03.12
09:47
(41) Дык это, начальник! Я же тоже тестер!
45 Спорт
 
29.03.12
09:48
(42) Вот тут прямыми богато http://www.1cpp.ru/forum/
46 Ёпрст
 
гуру
29.03.12
09:49
(41) ага, так и есть.. тестер из меня никакой.. а к халяве как то не привык.
:(
47 Ёпрст
 
гуру
29.03.12
09:50
(41) дык совсем недавно ставил - всё равно вылет, пришлось на 24 откатиться аварийно..
48 Ёпрст
 
гуру
29.03.12
09:51
хотя 26 работает шустрее на части запросов по сравнению с 24, почему - загадка :)
49 failures
 
29.03.12
10:15
(26) индексированная таблица не помогла, много времени уходит на построение индекса...
50 Mikeware
 
29.03.12
10:17
51 Он
 
29.03.12
10:21
(50) Что в файле?
52 Mikeware
 
29.03.12
10:23
(51)
2012-03-29 12:15        138022        138022  1cpp.rar
#  Архив 1cpp.rar
2006-11-02 11:20         26754          5962  1CPP_Classes.als
2008-06-02 19:59         14219          4269  1CppSQLTab.als
2010-06-03 15:16         85028         17274  1C++_Add.als
2008-03-27 14:25         60708         18576  Transact_SQL.als
2010-05-05 12:40        318857         68726  1C++.als
2010-05-05 12:40         43313          8706  ИндексированнаяТаблица.als
2010-05-05 12:40         64095         14103  ТабличоеПоле.als
#
# Всего:                Размер          Сжат  Файлы
#                       138022        138022  1
53 viktor_vv
 
29.03.12
10:23
(49) А индекс ты строишь по внутреннему идентификатору или по представлению ?
54 Он
 
29.03.12
10:25
(52) Transact_SQL.als - похоже то, что нужно. Остальное у меня есть.
Спасибо.
55 Mikeware
 
29.03.12
10:26
(54) там лишь выдержки из BOL. правда, на русском, но это кагбэ пофиг.
56 failures
 
29.03.12
10:28
(53) итз.ДобавитьИндекс("Ссылка","Ссылка");
57 Ёпрст
 
гуру
29.03.12
10:29
(56) *ССылка
58 viktor_vv
 
29.03.12
10:31
(56) итз.ДобавитьИндекс("Ссылка","*Ссылка");

так понятнее будет наверное.
59 failures
 
29.03.12
10:36
(57) Все равно индекс строится медленно... В таблице для поиска получается всегда больше 50 000 строк...
60 failures
 
29.03.12
10:38
Надо как-то этот поиск весь средствами sql организовать, иначе все равно все медленно работает...
61 Он
 
29.03.12
10:39
(55) Поставил. Посмотрел. Да - куце.
На безрыбье и рак рыба.

Как заставить Скуль2005 освободить память после завершения сеанса 1С?
На локальной 2-й тренируюсь.
62 Ёпрст
 
гуру
29.03.12
10:43
(61) как дружил с 2005, для начала ?
63 Mikeware
 
29.03.12
10:44
(60) у тебя точно вся цепочка подчинения - документы одного вида?
64 Он
 
29.03.12
10:50
(62) Дружили до меня.
Я просто взял дистрибут 2005-го, КаталогИБ и бэкап.
Дома поставил поднял - всё работает. Но память жрёт падлюка и не отдаёт после завершения сеанса 1С.
Чую, что в Студио что-то надо настроить. А что?
65 Ёпрст
 
гуру
29.03.12
10:52
(64) взять секретный релиз платформы и попробовать на нём, это для начала.
66 Андрюха
 
29.03.12
10:53
(65) Отче, надёже князь говорит, что память-то не 1С жрет, а SQL
67 Ёпрст
 
гуру
29.03.12
10:54
(66) дык мот он в соединениях скуля еще висит
68 Ёпрст
 
гуру
29.03.12
10:55
да и 1с-ина не сразу высвобождает ресуры после закрытия
69 Андрюха
 
29.03.12
10:57
1С на клиенте, а SQL на сервере я так понимаю выжирает
70 Ёпрст
 
гуру
29.03.12
10:59
(69) да не..он же дома, на домашнем компике всё делает
71 failures
 
29.03.12
11:00
(63) нет, там есть документы других видов. Но меня они не интересуют. К тому же если их обрабатывать, то будет зацикливание.
72 Андрюха
 
29.03.12
11:01
(70) Пхх... Дома-то чё, пускай лопает, в крайнем случае ресетнулся.
73 Ёпрст
 
гуру
29.03.12
11:02
(72) ну а порево как глядеть ? Тормозит же всё!
:)
74 Mikeware
 
29.03.12
11:07
(71) Если главная ветка цепочки - документы одного вида (скажем, заявки- коректирующие заявки), и тебе нужно найти корень (док с пустым основанием) - на мой взгляд, лучше всего рекурсивная функция.
Тем более, что тебе не нужна вся цепочка, и надо искать регулярно...
75 failures
 
29.03.12
11:24
(74) сейчас реализована рекурсивная функция, но она реализована как цикл... вопрос в том, что рекурсия большая, обращений много, и потому все делается медленно...
76 Mikeware
 
29.03.12
11:25
(75) сиквельную функцию
77 Андрюха
 
29.03.12
11:41
(76) Есть наброски?
78 failures
 
29.03.12
11:44
нет набросков. я же говорю, что начинающий, не знаю как сделать рекурсивный поиск в sql.
79 dk
 
29.03.12
11:51
(78) можно в скуле запросом, уровней на 5 просчитать
а потом остальные уровни в 1с допилить - т.к. допиливать скорее всего не придется, то скорость должна прилично возрасти
80 Mikeware
 
29.03.12
11:59
(77) как-то так:

CREATE FUNCTION DocRoot(@doc char(9))
RETURNS char(4)
AS
BEGIN
 DECLARE @CurDocRoot char(9)
 DECLARE @DocRoot char(9)
 SET @CurDocRoot = SELECT right($Заявка.ДокОснование,9)
   FROM $Документ.ЗаявкаПокупателя Заявка
  where Заявка.iddoc=@doc

  IF (@CurDocRoot=$ПустойИД)
     SET @DocRoot= @doc
  ELSE
     SET @DocRoot= Select dbo.DocRoot(@CurDocRoot)
RETURN(@DocRoot)
END
---------
у меня нет длинных цепочек, а в 1с лезть лениво...
81 Андрюха
 
29.03.12
12:17
(80) Не силен в SQL процедурах. И чё, этим можно пользоваться из 1С?
82 Ёпрст
 
гуру
29.03.12
12:18
(81) в клюшках - запросто!
83 Андрюха
 
29.03.12
12:20
научите!!!
84 Ёпрст
 
гуру
29.03.12
12:24
(83) чему ? хошь, по адо, хошь с помощью 1cpp
Или тебя научить писать пользовательские функции?
:)
85 Ёпрст
 
гуру
29.03.12
12:25
с 1сpp быстрее - есть встроенный метапарсер имён
86 Андрюха
 
29.03.12
12:27
Нее, пользовательскую функцию допустим я сам попытаюсь, а можно пример вызова из 1c++ чтобы с возвращением результата, скажем документа какого-нибудь
87 Гефест
 
29.03.12
12:29
(86) Вот например остаток на каждую дату в запросе без ВТ:

   ТекстЗапроса = "
   |declare @@curDate datetime
   |declare @@endDate datetime
   |
   |set @@curDate = cast('"+Дата1+"' AS datetime)  
   |set @@endDate = cast('"+Дата2+"' AS datetime)
   |
   |set nocount on
   |
   |
   |while @@curDate<=cast('"+Дата2+"' AS datetime)
   |begin
   |     insert into #DateTable(Товар,ОстатокТовара,Расход,Дата)
   |     SELECT
   |       Рег.Товар                [Товар],
   |       SUM(Рег.ОстатокТовара)    [ОстатокТовара],  
   |       SUM(Рег.Расход)            [ОстатокТовара],  
   |       @@curDate                [Дата]
   |     FROM
   |        (  
   |           SELECT
   |             $rg.Товар                    [Товар],
   |             $rg.ОстатокДляПродажи        [ОстатокТовара],  
   |             0                            [Расход]  
   |           FROM
   |             $РегистрИтоги.ОстаткиТоваров AS rg (nolock)
   |           WHERE
   |              rg.period = dateadd(m,-1,dateadd(dd,-day(@@curDate)+1,@@curDate))";
                   Если СписокНоменклатура.РазмерСписка()>0 Тогда    
                       ТекстЗапроса = ТекстЗапроса + "
                       |AND $rg.Товар IN (SELECT val FROM #СписокТоваров)";
                       ЗапросSQL.УложитьСписокОбъектов(СписокНоменклатура,"#СписокТоваров","Номенклатура");    
                   КонецЕсли;  
                   Если СписокСклады.РазмерСписка()>0 Тогда    
                       ТекстЗапроса = ТекстЗапроса + "
                       |AND $rg.Склад IN (SELECT val FROM #СписокСкладов)";
                       ЗапросSQL.УложитьСписокОбъектов(СписокСклады,"#СписокСкладов","МестаХранения");    
                   КонецЕсли;  
                   ТекстЗапроса = ТекстЗапроса + "
   |           UNION ALL
   |           SELECT
   |             $ra.Товар                                      [Товар],
   |             $ra.ОстатокДляПродажи*(1-ra.debkred*2)        [ОстатокТовара],  
   |             0                                                [Расход]  
   |           FROM
   |             $Регистр.ОстаткиТоваров ra (nolock)
   |           INNER JOIN
   |             _1sjourn j (nolock) on j.iddoc = ra.iddoc
   |           WHERE
   |              cast(left(j.date_time_iddoc,8) AS datetime) between dateadd(dd,-day(@@curDate)+1,@@curDate) AND @@curDate";
                   Если СписокНоменклатура.РазмерСписка()>0 Тогда    
                       ТекстЗапроса = ТекстЗапроса + "
                       |AND $ra.Товар IN (SELECT val FROM #СписокТоваров)";
                   КонецЕсли;    
                   Если СписокСклады.РазмерСписка()>0 Тогда    
                       ТекстЗапроса = ТекстЗапроса + "
                       |AND $ra.Склад IN (SELECT val FROM #СписокСкладов)";
                   КонецЕсли;    
                   ТекстЗапроса = ТекстЗапроса + "  
   |           UNION ALL  
   |
   |           SELECT
   |             $ra2.Товар                                      [Товар],
   |             0                                                [ОстатокТовара],  
   |             $ra2.ОстатокДляПродажи*ra2.DEBKRED            [Расход]  
   |           FROM
   |             $Регистр.ОстаткиТоваров ra2 (nolock)
   |           INNER JOIN
   |             _1sjourn j (nolock) on j.iddoc = ra2.iddoc
   |           WHERE
   |              cast(left(j.date_time_iddoc,8) AS datetime) = @@curDate";
                   Если СписокНоменклатура.РазмерСписка()>0 Тогда    
                       ТекстЗапроса = ТекстЗапроса + "
                       |AND $ra2.Товар IN (SELECT val FROM #СписокТоваров)";
                   КонецЕсли;      
                   Если СписокСклады.РазмерСписка()>0 Тогда    
                       ТекстЗапроса = ТекстЗапроса + "
                       |AND $ra2.Склад IN (SELECT val FROM #СписокСкладов)";
                   КонецЕсли;      
                   ТекстЗапроса = ТекстЗапроса + "
   |           UNION ALL
   |
   |           SELECT
   |             $ra3.Товар                                      [Товар],
   |             0                                                [ОстатокТовара],  
   |             0                                                [Расход]  
   |           FROM
   |             $Регистр.ОстаткиТоваров ra3 (nolock)
   |           INNER JOIN
   |             _1sjourn j (nolock) on j.iddoc = ra3.iddoc
   |           WHERE
   |              cast(left(j.date_time_iddoc,8) AS datetime) between @@curDate AND @@endDate";
                   Если СписокНоменклатура.РазмерСписка()>0 Тогда    
                       ТекстЗапроса = ТекстЗапроса + "
                       |AND $ra3.Товар IN (SELECT val FROM #СписокТоваров)";
                   КонецЕсли;          
                   Если СписокСклады.РазмерСписка()>0 Тогда    
                       ТекстЗапроса = ТекстЗапроса + "
                       |AND $ra3.Склад IN (SELECT val FROM #СписокСкладов)";
                   КонецЕсли;          
                   ТекстЗапроса = ТекстЗапроса + "  
   |        ) Рег  
   |     GROUP BY
   |        Рег.Товар
   |     set @@curDate = dateadd(dd,1,@@curDate)
   |  end
   |";    
   
   

   рез = ЗапросSQL.Выполнить(ТекстЗапроса);
   Если рез = 0 Тогда
       Сообщить(ЗапросSQL.ПолучитьОписаниеОшибки());
       Возврат;
   КонецЕсли;
88 Андрюха
 
29.03.12
12:32
(87) О, спасибо!
89 Mikeware
 
29.03.12
12:37
(83)
рс=создатьОбъект("ODBCRecordSet");
рс.УстановитьТекстовыйПараметр("ВыбДокумент",ДокументКореньКоторогоИщем)$
Корень=рс.ВыполнитьСкалярный("select dbo.DocRoot(:ВыбДокумент)");
90 Ёпрст
 
гуру
29.03.12
12:41
(87) вот будет другая периодичность хранения останкови и усё, писец котёнку
:)
91 Ёпрст
 
гуру
29.03.12
12:43
да и.. проще как то табличку с датами соединить с запросам по останкам, и в нём группировку по дате слепить..
92 Mikeware
 
29.03.12
12:43
(91) албанские пионеры не ищут простых путей!
93 Андрюха
 
29.03.12
12:47
(89) И ШО РАБОТАЕТ???
94 Гефест
 
29.03.12
12:48
(90) Это негарантийный случай!
(91) В те даты, когда не было движений, остаток будет null. А тут фсе есть
95 Андрюха
 
29.03.12
12:50
Плин, если в (89) рабочий вариант, то можно начинать ср@ть кирпичами от счастья...
96 Ёпрст
 
гуру
29.03.12
12:51
(94) дык с табличкой дат соединяешься и там coalesce(0,запросПоОстанкам.Остаток)

ну хотя, работает и ладно
97 viktor_vv
 
29.03.12
12:51
(95) Кажись только начиная с 2005 MSSQL, если ничего не путаю.
98 viktor_vv
 
29.03.12
12:52
(97)+ Наверное путаю, это про рекурсивные запросы.
99 Андрюха
 
29.03.12
12:53
Пошёл пробувати
100 Андрюха
 
29.03.12
12:53
100 кстати
101 Гефест
 
29.03.12
12:55
(96) Дык остаток-то не 0, а некое число
102 Андрюха
 
29.03.12
12:56
Ругается. Cannot find either column "dbo" or the user-defined function or aggregate "dbo.DocRoot", or the name is ambiguous.

ЧЯДНТ?
103 Ёпрст
 
гуру
29.03.12
12:58
(101) не вкурил твою мыслю.
104 Mikeware
 
29.03.12
12:58
(102) так функцию-то создал?
105 Mikeware
 
29.03.12
12:58
(101) а ноль - это  буква, чтоль?
106 Z1
 
29.03.12
13:02
(87) Вместо
cast(left(j.date_time_iddoc,8) AS datetime) between ...
надо наоборот  дату(ы) преобразовывать в строку

j.date_time_iddoc between Стр_дата1 and Стр_Дата2

ну и еще в 87 нет как создается #DateTable и какие на ней индексы
107 Гефест
 
29.03.12
13:03
(103) Например, на первое число остаток 10, второго и третьего числа движений по регистру нет

Если я соединю таблицу дат с ВТ ОстаткиИОбороты по твоему способу, то остаток будет на первое число 10, на второе и третье число остаток 0. А должен быть 10
108 viktor_vv
 
29.03.12
13:04
(96) А разве не Isnull()? coalesce() в таком варианте всегода 0 вернет по идее.
109 Андрюха
 
29.03.12
13:04
(104) Неа )))
110 Ёпрст
 
гуру
29.03.12
13:11
(107) а.. ты об этом
(108) ага, но смысл понятен
111 Mikeware
 
29.03.12
13:13
(109) дык!
112 Z1
 
29.03.12
14:51
(87) Вы понимаете что запрос надо обязательно
улучшить как написано в (106)  ?
113 Он
 
29.03.12
16:18
ТекстЗапроса = "
   |SELECT Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура], Рег.КоличествоОстаток as Количество
   |FROM $РегистрОстатки.ОстаткиТМЦ (:НаДату,, (Номенклатура),,, (Количество)) as Рег";
   //|FROM $РегистрОстатки.ОстаткиТМЦ as Рег";
   RS.УстановитьТекстовыйПараметр("НаДату", ВыбДата);
   ТЗ = RS.ВыполнитьИнструкцию(ТекстЗапроса);

ВыбДата - реквизит на форме типа Дата

Выдаёт:
{C:\BASE1C\ERT\ПРЯМЫЕ.ERT(32)}: State 42000, native 102, message [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near '20120101'.

Что не так делаю?
114 viktor_vv
 
29.03.12
16:34
|FROM $РегистрОстатки.ОстаткиТМЦ (:НаДату,, ,(Номенклатура),(Количество) ) as Рег";
115 viktor_vv
 
29.03.12
16:35
И на конец дня надо :НаДату~
116 Он
 
29.03.12
16:36
(114) Измерение "Номенклатура" 2-е из 4-х
117 Mikeware
 
29.03.12
16:37
(116) пофиг.
читай список параметров
118 Он
 
29.03.12
16:39
(115)
{C:\BASE1C\ERT\ПРЯМЫЕ.ERT(33)}: State 42000, native 102, message [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near '20111231Z'.

Надо видимо как то преобразовать ВыбДата.
В статье Акцента напрямую ставятся
119 Mikeware
 
29.03.12
16:40
(118) запятую поставил?
120 Он
 
29.03.12
16:41
(114) Сделал как в (114). Результат тот же.
121 Он
 
29.03.12
16:42
Подставлял ПолучитьПозициюДокумента.
Тоже выплёвывает.
122 viktor_vv
 
29.03.12
16:43
RS.УстановитьТекстовыйПараметр("НаДату", ВыбДата);
RS.Отладка(1);
   ТЗ = RS.ВыполнитьИнструкцию(ТекстЗапроса);

RS.Отладка(0);

Правда вывалит дофига наверное.
123 Он
 
29.03.12
16:47
SELECT Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура], Рег.КоличествоОстаток as Количество
FROM (
select
rg405_vt.sp4062 as Фирма,
rg405_vt.sp408 as Номенклатура,
rg405_vt.sp418 as Склад,
rg405_vt.sp3117 as ЦенаПрод,
rg405_vt.sp411 as КоличествоОстаток,
rg405_vt.sp10260 as КолВоСВОстаток,
rg405_vt.sp11365 as ВесОстаток
from rg405 as rg405_vt (nolock)
where rg405_vt.period={d '2012-03-01'}
and (
rg405_vt.sp411 <> 0 or
rg405_vt.sp10260 <> 0 or
rg405_vt.sp11365 <> 0
)
124 Mikeware
 
29.03.12
16:49
SELECT Остатки.Номенклатура [Номенклатура $Справочник.Номенклатура]
   , Остатки.КоличествоОстаток
FROM $РегистрОстатки.ОстаткиТМЦ(:ВыбДата~,,,
       (Номенклатура),(Количество)) as Остатки
125 Он
 
29.03.12
16:57
(124) Пробовал.
Упростил:

   ТекстЗапроса = "
   |SELECT Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура], Рег.КоличествоОстаток as Количество
   //|FROM $РегистрОстатки.ОстаткиТМЦ (:НаДату,,, (Номенклатура), (Количество)) as Рег";
   |FROM $РегистрОстатки.ОстаткиТМЦ (:НаДату) as Рег";
   RS.УстановитьТекстовыйПараметр("НаДату", ВыбДата);

Та же граната
126 viktor_vv
 
29.03.12
17:02
|FROM $РегистрОстатки.ОстаткиТМЦ(:НаДату) as Рег";

Пробел убери  $РегистрОстатки.ОстаткиТМЦ (:НаДату) as Рег"
127 Ёпрст
 
гуру
29.03.12
17:03
(124) и база поди формата ДБФ ?
:)))))))))))))))))))))))))))))))))))))))))))
128 Он
 
29.03.12
17:14
Пипец!!!
Дело в пробеле было *нервный смех*

(126) Спасибо!
129 Он
 
29.03.12
17:15
Прямым получилось в 53 раза быстрее сделать ВыгрузитьИтоги()
130 Он
 
29.03.12
17:19
Я так понимаю - СводныйОстаток() будет также с добавлением WHERE.
Так?
131 Ёпрст
 
гуру
29.03.12
17:21
(129) что то у тебя не так с базо, либо ты не то делаешь
если на ТА то выирышь небольшой, если на отличную от ТА дату - то да, выигрышь будет за счет пересчета итогов
132 viktor_vv
 
29.03.12
17:25
Че-то как-то да, сильно быстро. Обычно этои операции не особо отличаются по скорости. Тем более учитывая во что у тебя развернулась ВТ, то берешь ты на ТА остатки.
133 Он
 
29.03.12
17:25
(131) На ТА ВыгрузитьИтоги() отработало раз в 10 быстрее прямого

А вот на дату.
Базу обследую на предмет косяков перед свёрткой. Незакрытых регистров несколько уже нашёл.
134 viktor_vv
 
29.03.12
17:27
(130) Сводный остаток будет с указанием только необходимых измерений в параметрах ВТ.
135 Он
 
29.03.12
17:27
ТекстЗапроса = "
   |SELECT Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура], Рег.КоличествоОстаток as Количество
   //|FROM $РегистрОстатки.ОстаткиТМЦ (:НаДату,,, (Номенклатура), (Количество)) as Рег";
   |FROM $РегистрОстатки.ОстаткиТМЦ(:НаДату) as Рег";
   RS.УстановитьТекстовыйПараметр("НаДату", ВыбДата);
   ТЗ = RS.ВыполнитьИнструкцию(ТекстЗапроса);
   Сообщить("" + ТЗ.КоличествоСтрок() + " = " + (_GetPerformanceCounter() - Нач) / 1000);
   ТЗ.Выгрузить(Тпр);
   Тпр.Свернуть("Номенклатура", "Количество");
   Тпр.Сортировать("Номенклатура");
   Форма.Обновить();
   
   Нач = _GetPerformanceCounter();
   Рег = СоздатьОбъект("Регистр.ОстаткиТМЦ");
   Рег.ВременныйРасчет(1);
   РассчитатьРегистрыНа(ВыбДата);
   Рег.ВыгрузитьИтоги(ТЗ);
   Сообщить("" + ТЗ.КоличествоСтрок() + " = " + (_GetPerformanceCounter() - Нач) / 1000);
   ТЗ.Выгрузить(Т);
   Т.Свернуть("Номенклатура", "Количество");
   Т.Сортировать("Номенклатура");

Две ТЗ перед глазами. Абсолютно идентичны.
136 Он
 
29.03.12
17:30
(134) Это понятно.
Сделал на 01.01.08. Результат (сек):
0.006
0.399
137 Mikeware
 
29.03.12
17:35
(136) разница в том, что временный расчет считает сначала, а виртуальная таблица - с того конца, откуда быстрее.
и в этом, кстати, есть и засада
138 Он
 
29.03.12
17:36
(137) Надо запомнить.
Ща попробую на 01.01.05
139 Mikeware
 
29.03.12
17:38
+(137) сворачивать не надо, после запроса все и так будет свернуто по номенклатуре.
а
left join $Справочник.Номенклатура Спр (nolock) on Спр.id=Остатки.Номенклатура
group by Спр.descr
сразу даст и отсортированную
140 Mikeware
 
29.03.12
17:40
+(139) а если выгрузить оба запроса в индексированные таблицы, и применить Разность() - получишь различия
141 Он
 
29.03.12
17:42
(139) После ВыгрузитьИтоги() надо свернуть. Поэтому и эту свернул для чистоты эксремента.

(139) Рано ещё мне такие прибамбасы. Я только что свой первый работающий запрос написал.
142 Ёпрст
 
гуру
29.03.12
17:43
(141) Зачем сворачивать после выгрузитьИтоги ?
143 Он
 
29.03.12
17:44
(142) Там ТЗ со всеми измерениями и ресурсами.
144 Ёпрст
 
гуру
29.03.12
17:45
(143) а ну да, фильтры то ты не установил
145 viktor_vv
 
29.03.12
17:46
(139) Order by , а то сейчас насворачиваешь ему по наименованию :).
146 Mikeware
 
29.03.12
17:47
(145) каюсь, грешен.
приспичило сейчас обновить старый отчет, воюю с группировками - вот и вырвалось...
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший