Имя: Пароль:
1C
1С v8
Прошу помощи: Прямой запрос к таблице партий товаров (остатки)
0 Eugene_life
 
28.08.14
18:22
Пытаюсь решить задачу чтения актуальных складских остатков 1С (УТ 10.3, версия SQL) из сторонней программы. Как запасной вариант держу возможность заполнения по регламенту внешней таблицы, к которой будет эта сторонняя программа обращаться. Но основным вариантом пытаюсь дать сторонним программистам SQL-скрипт для получения актуальных остатков из таблиц 1С. Запрос в 1С выглядит так:
ВЫБРАТЬ
    Ном.Родитель,
    Ном.Ссылка,
    ПартииТоваровНаСкладахОстатки.Склад,
    ПартииТоваровНаСкладахОстатки.Организация,
    ПартииТоваровНаСкладахОстатки.КоличествоОстаток,
    ПартииТоваровНаСкладахОстатки.СтоимостьОстаток
ИЗ
    Справочник.Номенклатура КАК Ном
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровНаСкладах.Остатки(&ТекущаяДата, ) КАК ПартииТоваровНаСкладахОстатки
        ПО (ПартииТоваровНаСкладахОстатки.Номенклатура = Ном.Ссылка)

но получить рабочий вариант на языке T-SQL у меня не получается (использую SQL Profiler).
Возможно, кто-то подскажет нужное направление или поделится рабочим примером.
1 ДенисЧ
 
28.08.14
18:28
Нарушаем-сЪ?
2 zak555
 
28.08.14
18:30
(1) запрос sql что-то нарушает ?
3 МихаилМ
 
28.08.14
18:36
(0)
включите режим debug
(1) для 7.7 , купленной до 2008г не нарушает.
4 ShoGUN
 
28.08.14
18:36
(3) Лицензионное соглашение. Увы :)
5 ShoGUN
 
28.08.14
18:36
(4) к (2).
(3) В (0) запрос из восьмёрки.
6 Ёпрст
 
гуру
28.08.14
18:37
(0) А чего не получается то ? Поймать запрос в профайлере, или что ?

Там тупо запрос к двум табличкам в юнионе будет
7 Eugene_life
 
28.08.14
18:37
(4) Да я знаю, что это - нарушение лицензионного соглашения 1С :)
8 Ёпрст
 
гуру
28.08.14
18:37
+6 это для получения останков
9 Eugene_life
 
28.08.14
18:38
(6) Поймать получается.. не получается заставить его работать в SQL, в окне запроса
10 Eugene_life
 
28.08.14
18:38
(8) Там не простое объединение.. там же надо взять актуальные остатки и рассчитать текущие? или я неправильно понимаю..
11 МихаилМ
 
28.08.14
18:40
+(3)
извиняюсь. перепутал с 1с77.

можно текст запроса подсмотреть в ТЖ.

есть спец консоль запросов, которая показывает текст tsql

в наборе разработчика вроде
12 МихаилМ
 
28.08.14
18:41
(10)
не павильно. актуальные хранятся в таблице итогов со смещением +3999 лет.
13 Eugene_life
 
28.08.14
18:42
(12) А таблица актуальных остатков - это то же самое, что и реальная таблица регистра? или отдельно находится?
14 mehfk
 
28.08.14
18:42
exec sp_executesql N'SELECT
T1._ParentIDRRef,
T1._IDRRef,
T2.Fld7511RRef,
T2.Fld7518Balance_,
T2.Fld7519Balance_
FROM _Reference70 T1 WITH(NOLOCK)
LEFT OUTER JOIN (SELECT
T3._Fld7510RRef AS Fld7510RRef,
T3._Fld7511RRef AS Fld7511RRef,
CAST(SUM(T3._Fld7519) AS NUMERIC(33, 8)) AS Fld7519Balance_,
CAST(SUM(T3._Fld7518) AS NUMERIC(32, 8)) AS Fld7518Balance_
FROM _AccumRgT7529 T3 WITH(NOLOCK)
WHERE T3._Period = P1
GROUP BY T3._Fld7510RRef,
T3._Fld7511RRef
HAVING (CAST(SUM(T3._Fld7519) AS NUMERIC(33, 8))) <> @P2 OR (CAST(SUM(T3._Fld7518) AS NUMERIC(32, 8))) <> @P3) T2
ON (T2.Fld7510RRef = T1._IDRRef)', N'P1 datetime,@P2 numeric(10),@P3 numeric(10)', 'Nov  1 5999 12:00:00:000AM', 0, 0
15 mehfk
 
28.08.14
18:43
Регистр партии товаров у вас нетиповой
16 Ёпрст
 
гуру
28.08.14
18:45
(10) если текущие останки - запрос будет к одной табличке, если на произвольную дату - то юнион к двум, к табличке итогов  + сумма движений до даты с начала прошлой периодичности итогов
17 Eugene_life
 
28.08.14
18:46
(15) я вот такой запрос и сам получил.. но не смог его заставить работать в Management Studio
18 Eugene_life
 
28.08.14
18:46
(16) мне всегда нужны остатки на ТекущаяДата()
19 Eugene_life
 
28.08.14
18:47
(16) + как найти эту таблицу с актуальными остатками?
20 МихаилМ
 
28.08.14
18:51
(16)
в 1c8.2 сделали , как в 1с++ - в зависимости о близости границы хранения итогов расчет может вычитать движения из следующих остатков.
21 МихаилМ
 
28.08.14
18:52
(13)
да . то же самое.
22 mehfk
 
28.08.14
18:55
(17) Тогда вот так
SELECT
T1._ParentIDRRef,
T1._IDRRef,
T2.Fld7511RRef,
T2.Fld7518Balance_,
T2.Fld7519Balance_
FROM _Reference70 T1 WITH(NOLOCK)
LEFT OUTER JOIN (SELECT
T3._Fld7510RRef AS Fld7510RRef,
T3._Fld7511RRef AS Fld7511RRef,
CAST(SUM(T3._Fld7519) AS NUMERIC(33, 8)) AS Fld7519Balance_,
CAST(SUM(T3._Fld7518) AS NUMERIC(32, 8)) AS Fld7518Balance_
FROM _AccumRgT7529 T3 WITH(NOLOCK)
WHERE T3._Period = 'Nov  1 5999 12:00:00:000AM'
GROUP BY T3._Fld7510RRef,
T3._Fld7511RRef
HAVING (CAST(SUM(T3._Fld7519) AS NUMERIC(33, 8))) <> 0.0 OR (CAST(SUM(T3._Fld7518) AS NUMERIC(32, 8))) <> 0.0) T2
ON (T2.Fld7510RRef = T1._IDRRef)
23 Eugene_life
 
28.08.14
19:00
(22) А что у тебя за таблица в _AccumRgT7529 ?
24 mehfk
 
28.08.14
19:08
Запрос подходит для случая когда ТекущаяДата не заполнена. Если хотите на произвольную дату - запрос будет другой.
25 Eugene_life
 
28.08.14
19:19
нет, мне на произвольную не надо. Но таблицы AccumRgT7529 у меня в базе просто нет.
мой Профайлер выдает вот такое:
exec sp_executesql N'SELECT
T1._ParentIDRRef,
T1._IDRRef,
T2.Fld7479RRef,
T2.Fld8138RRef,
T2.Fld7486Balance_,
T2.Fld7487Balance_
FROM _Reference70 T1 WITH(NOLOCK)
LEFT OUTER JOIN (SELECT
T3.Fld7478RRef AS Fld7478RRef,
T3.Fld7479RRef AS Fld7479RRef,
T3.Fld8138RRef AS Fld8138RRef,
CAST(SUM(T3.Fld7487Balance_) AS NUMERIC(38, 8)) AS Fld7487Balance_,
CAST(SUM(T3.Fld7486Balance_) AS NUMERIC(38, 8)) AS Fld7486Balance_
FROM (SELECT
T4._Fld7478RRef AS Fld7478RRef,
T4._Fld7479RRef AS Fld7479RRef,
T4._Fld8138RRef AS Fld8138RRef,
CAST(SUM(T4._Fld7487) AS NUMERIC(33, 8)) AS Fld7487Balance_,
CAST(SUM(T4._Fld7486) AS NUMERIC(32, 8)) AS Fld7486Balance_
FROM _AccumRgT7497 T4 WITH(NOLOCK)
WHERE T4._Period = P1
GROUP BY T4._Fld7478RRef,
T4._Fld7479RRef,
T4._Fld8138RRef
HAVING (CAST(SUM(T4._Fld7487) AS NUMERIC(33, 8))) <> @P2 OR (CAST(SUM(T4._Fld7486) AS NUMERIC(32, 8))) <> @P2
UNION ALL SELECT
T5._Fld7478RRef AS Fld7478RRef,
T5._Fld7479RRef AS Fld7479RRef,
T5._Fld8138RRef AS Fld8138RRef,
CAST(CAST(SUM(CASE WHEN T5._RecordKind = 0.0 THEN -T5._Fld7487 ELSE T5._Fld7487 END) AS NUMERIC(27, 8)) AS NUMERIC(27, 2)) AS Fld7487Balance_,
CAST(CAST(SUM(CASE WHEN T5._RecordKind = 0.0 THEN -T5._Fld7486 ELSE T5._Fld7486 END) AS NUMERIC(26, 8)) AS NUMERIC(27, 3)) AS Fld7486Balance_
FROM _AccumRg7477 T5 WITH(NOLOCK)
WHERE T5._Period >= @P3 AND T5._Period < P1 AND T5._Active = @P4
GROUP BY T5._Fld7478RRef,
T5._Fld7479RRef,
T5._Fld8138RRef
HAVING (CAST(CAST(SUM(CASE WHEN T5._RecordKind = 0.0 THEN -T5._Fld7487 ELSE T5._Fld7487 END) AS NUMERIC(27, 8)) AS NUMERIC(27, 2))) <> @P2 OR (CAST(CAST(SUM(CASE WHEN T5._RecordKind = 0.0 THEN -T5._Fld7486 ELSE T5._Fld7486 END) AS NUMERIC(26, 8)) AS NUMERIC(27, 3))) <> @P2) T3
GROUP BY T3.Fld7478RRef,
T3.Fld7479RRef,
T3.Fld8138RRef
HAVING (CAST(SUM(T3.Fld7487Balance_) AS NUMERIC(38, 8))) <> @P2 OR (CAST(SUM(T3.Fld7486Balance_) AS NUMERIC(38, 8))) <> @P2) T2
ON (T2.Fld7478RRef = T1._IDRRef)', N'P1 datetime,@P2 numeric(1,0),@P3 datetime,@P4 varbinary(1)', {ts '5999-11-01 00:00:00'}, 0, {ts '4014-08-28 00:00:00'}, 0x01

а как это заставить работать - я не знаю.
26 mehfk
 
28.08.14
19:24
Тогда так
SELECT
T1._ParentIDRRef,
T1._IDRRef,
T2.Fld7479RRef,
T2.Fld8138RRef,
T2.Fld7486Balance_,
T2.Fld7487Balance_
FROM _Reference70 T1 WITH(NOLOCK)
LEFT OUTER JOIN (SELECT
T3.Fld7478RRef AS Fld7478RRef,
T3.Fld7479RRef AS Fld7479RRef,
T3.Fld8138RRef AS Fld8138RRef,
CAST(SUM(T3.Fld7487Balance_) AS NUMERIC(38, 8)) AS Fld7487Balance_,
CAST(SUM(T3.Fld7486Balance_) AS NUMERIC(38, 8)) AS Fld7486Balance_
FROM (SELECT
T4._Fld7478RRef AS Fld7478RRef,
T4._Fld7479RRef AS Fld7479RRef,
T4._Fld8138RRef AS Fld8138RRef,
CAST(SUM(T4._Fld7487) AS NUMERIC(33, 8)) AS Fld7487Balance_,
CAST(SUM(T4._Fld7486) AS NUMERIC(32, 8)) AS Fld7486Balance_
FROM _AccumRgT7497 T4 WITH(NOLOCK)
WHERE T4._Period = P1
GROUP BY T4._Fld7478RRef,
T4._Fld7479RRef,
T4._Fld8138RRef
HAVING (CAST(SUM(T4._Fld7487) AS NUMERIC(33, 8))) <> 0.0 OR (CAST(SUM(T4._Fld7486) AS NUMERIC(32, 8))) <> 0.0
UNION ALL SELECT
T5._Fld7478RRef AS Fld7478RRef,
T5._Fld7479RRef AS Fld7479RRef,
T5._Fld8138RRef AS Fld8138RRef,
CAST(CAST(SUM(CASE WHEN T5._RecordKind = 0.0 THEN -T5._Fld7487 ELSE T5._Fld7487 END) AS NUMERIC(27, 8)) AS NUMERIC(27, 2)) AS Fld7487Balance_,
CAST(CAST(SUM(CASE WHEN T5._RecordKind = 0.0 THEN -T5._Fld7486 ELSE T5._Fld7486 END) AS NUMERIC(26, 8)) AS NUMERIC(27, 3)) AS Fld7486Balance_
FROM _AccumRg7477 T5 WITH(NOLOCK)
WHERE T5._Period >= '4014-08-28 00:00:00' AND T5._Period < '5999-11-01 00:00:00' AND T5._Active = 0x01
GROUP BY T5._Fld7478RRef,
T5._Fld7479RRef,
T5._Fld8138RRef
HAVING (CAST(CAST(SUM(CASE WHEN T5._RecordKind = 0.0 THEN -T5._Fld7487 ELSE T5._Fld7487 END) AS NUMERIC(27, 8)) AS NUMERIC(27, 2))) <> 0.0 OR (CAST(CAST(SUM(CASE WHEN T5._RecordKind = 0.0 THEN -T5._Fld7486 ELSE T5._Fld7486 END) AS NUMERIC(26, 8)) AS NUMERIC(27, 3))) <> 0.0) T3
GROUP BY T3.Fld7478RRef,
T3.Fld7479RRef,
T3.Fld8138RRef
HAVING (CAST(SUM(T3.Fld7487Balance_) AS NUMERIC(38, 8))) <> 0.0 OR (CAST(SUM(T3.Fld7486Balance_) AS NUMERIC(38, 8))) <> 0.0) T2
ON (T2.Fld7478RRef = T1._IDRRef)
27 mehfk
 
28.08.14
19:28
Пропустил

WHERE T4._Period = P1
поменять на
WHERE T4._Period = '4014-08-28 00:00:00'
28 Eugene_life
 
28.08.14
19:28
(26) Что-то похожее на правду получилось.
А вот в этой строке: T4._Period = P1 вместо P1 подставить какую дату нужно?
29 Eugene_life
 
28.08.14
19:30
(26)+ И вывело ошибку:" Преобразование типа данных varchar в тип данных datetime привело к выходу значения за пределы диапазона" с указанием верхнего SELECT :(
30 Eugene_life
 
28.08.14
19:31
Ладно, спасибо всем участвовавшим.. думаю, я дальше смогу сам добиться результата. Общее направление уже есть, и понимание, как это должно работать - тоже.
Отдельное спасибо mehfk