Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Оборотная ведомость
|
|||
|---|---|---|---|
|
#18+
Кто нибудь пробовал написать оборотную ведомость (бухгалтерия) а то у меня, что то не красиво получается CREATE PROCEDURE Buh_Оборотка @n1 datetime, @n2 datetime, @userid int AS set nocount on delete from M__ТаблицаДляОтчетов where USER_UID=@userid insert into M__ТаблицаДляОтчетов( USER_UID, cField1, cField2, nField1, nField2, nField3, nField4, nField5, nField6) select @userid, COD, NAMES, isnull(sum(nSD),0) nSD, isnull(sum(nSK),0) nSK, isnull(sum(OD),0) OD, isnull(sum(OK),0) OK, isnull(sum(kSD),0) kSD, isnull(sum(kSK),0) kSK from M__PLAN p left join ( select SMK, dbo.BuhSaldoD( SDn, IN_ACTIV, IN_PASSIV) nSD, -- Сальдо дебет dbo.BuhSaldoK( -SDn, IN_ACTIV, IN_PASSIV) nSK, -- Сальдо кредит OD, -- Оборот дебет OK, -- Оборот кредит dbo.BuhSaldoD( SDk, IN_ACTIV, IN_PASSIV) kSD, -- Сальдо кредит dbo.BuhSaldoK( -SDk, IN_ACTIV, IN_PASSIV) kSK -- Сальдо кредит from ( select SMK, sum(SD)-sum(SK) as SDn, sum(OD) as OD, sum(OK) as OK, sum(SD)-sum(SK)+sum(OD)-sum(OK) SDk from ( -- Сальдо дебет на начало select SMKD "SMK", SUMD SD, 0 SK, 0 OD, 0 OK from B_ЖурналПроводок where OPER_ID in (select OPER_UID from B_ЖурналОпераций where OPER_DATE < @n1) union all -- Сальдо кредит на начало select SMKK "SMK", 0 SD, SUMD SK, 0 OD, 0 OK from B_ЖурналПроводок where OPER_ID in (select OPER_UID from B_ЖурналОпераций where OPER_DATE < @n1) union all -- Оборот по дебету select SMKD "SMK", 0 SD, 0 SK, SUMD OD, 0 OK from B_ЖурналПроводок where OPER_ID in (select OPER_UID from B_ЖурналОпераций where OPER_DATE between @n1 and @n2) union all -- Оборот по кредиту select SMKK "SMK", 0 SD, 0 SK, 0 OD, SUMD SK from B_ЖурналПроводок where OPER_ID in (select OPER_UID from B_ЖурналОпераций where OPER_DATE between @n1 and @n2) ) x group by SMK ) y left join M__PLAN p on p.COD=y.SMK where (IN_ACTIV=1 or IN_PASSIV=1) and rtrim(SMK)<>'00' ) ob on ob.SMK like rtrim(p.COD)+'%' where nSD<>0 or nSK<>0 or OD<>0 or OK<>0 or kSD<>0 or kSK<>0 group by COD, NAMES order by COD ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.06.2001, 08:39 |
|
||
|
Оборотная ведомость
|
|||
|---|---|---|---|
|
#18+
Ну я например так написал, тоже наверное не шедевр. Будете разбираться? (Я например Ваше творчество не стал смотреть, не потому что плохо или непонятно написано - ну лень разбираться, до и своё время ценю немного.) Единственно что посоветовал бы - не старайтесь делать всё в одном запросе. \ncreate procedure p_osv @bln varchar(10), @fond varchar(20), @date1 datetime, @date2 datetime AS BEGIN declare @z999 varchar(30) set nocount on select @z999='99999999999' create table #p( acc varchar(30), si dec(19,6), d dec(19,6), c dec(19,6), so dec(19,6)) create table #t( t int, acc varchar(30) null, sub varchar(30) null, num varchar(30) null, name varchar(300) null, type int null, si dec(19,6) null, ai dec(19,6) null, pi dec(19,6) null, d dec(19,6) null, c dec(19,6) null, so dec(19,6) null, ao dec(19,6) null, po dec(19,6) null, cnt int null) --- t --- -- 10 - состояние лицевого счета -- 20 - состояния субсчета -- 30 - состояния б.счета select acc, max(date) d into #d from AccState (nolock) where bln=@bln and fond=@fond and date<@date1 group by acc insert #p select d.acc, s,0,0, s from #d d, AccState s(nolock) where d.acc=s.acc and d=date and bln=@bln and fond=@fond insert #p select acc, 0, dt, cr, dt-cr from AccState s(nolock) where date between @date1 and @date2 and bln=@bln and fond=@fond insert #t(t,acc,si,d,c,so) select 10, acc, sum(si), sum(d), sum(c), sum(so) from #p group by acc update #t set type=a.type, name=a.name, sub=a.sub from #t t, Acc a where t.acc=a.acc and bln=@bln and fond=@fond update #t set ai= case when (type=1) or (type=3 and si>0) then si else 0 end, pi= case when (type=2) or (type=3 and si<0) then -si else 0 end, ao= case when (type=1) or (type=3 and so>0) then so else 0 end, po= case when (type=2) or (type=3 and so<0) then -so else 0 end insert #t(t, sub, acc, ai,pi, d,c, ao,po) select 20,sub,@z999,sum(ai),sum(pi),sum(d),sum(c),sum(ao),sum(po) from #t where t=10 group by sub update #t set type=a.type, name=a.name, num=a.num from #t t, PlnSub a where t=20 and a.sub=t.sub and bln=@bln update #t set num=a.num from #t t, PlnSub a where t=10 and a.sub=t.sub and bln=@bln insert #t(t, num, sub, acc, ai,pi, d,c, ao,po) select 30, num,@z999,@z999,sum(ai),sum(pi),sum(d),sum(c),sum(ao),sum(po) from #t where t=20 group by num update #t set name=n.name from #t t, PlnNum n where t=30 and n.num=t.num and bln=@bln insert #t(t,num,sub,acc,name) select -t, num, case when t=20 then sub else '' end,'', name from #t where t in (20,30) select sub ss, count(*) c into #t20 from #t where t=10 group by sub update #t set cnt=c.c from #t20 c where t=-20 and ss=sub select num n, count(*) c2, sum(cnt) c into #t30 from #t where t=-20 group by num update #t set cnt=c.c+c2*2 from #t30 c where t=-30 and n=num set nocount off select t , acc , sub , num , name , type , case @bln when 'D' then convert(varchar(20),convert(int,ai)) when 'M' then convert(varchar(20),convert(money,ai)) when 'P' then convert(varchar(20),ai) else '***' end ai, case @bln when 'D' then convert(varchar(20),convert(int,pi)) when 'M' then convert(varchar(20),convert(money,pi)) when 'P' then convert(varchar(20),pi) else '***' end pi, case @bln when 'D' then convert(varchar(20),convert(int,d)) when 'M' then convert(varchar(20),convert(money,d)) when 'P' then convert(varchar(20),d) else '***' end d, case @bln when 'D' then convert(varchar(20),convert(int,c)) when 'M' then convert(varchar(20),convert(money,c)) when 'P' then convert(varchar(20),c) else '***' end c, case @bln when 'D' then convert(varchar(20),convert(int,ao)) when 'M' then convert(varchar(20),convert(money,ao)) when 'P' then convert(varchar(20),ao) else '***' end ao, case @bln when 'D' then convert(varchar(20),convert(int,po)) when 'M' then convert(varchar(20),convert(money,po)) when 'P' then convert(varchar(20),po) else '***' end po, cnt from #t order by num, sub,acc,t END ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2001, 06:07 |
|
||
|
Оборотная ведомость
|
|||
|---|---|---|---|
|
#18+
Спасибо за ответ /пока правда не врубился/ Есть два вопроса: 1) что означают параметры - @bln varchar(10), @fond varchar(20) 2) Описание (SQL script) таблиц - AccState, Acc, PlnSub ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2001, 15:01 |
|
||
|
Оборотная ведомость
|
|||
|---|---|---|---|
|
#18+
Вообще-то я кинул без надежды на то, что в этом можно разобраться. Чтобы показать что не стоит показывать свои огромные процедуры в надежде что кто-нибудь посмотрит на них и поможет - смысла нет. Но на вопросы конечно отвечу. 1. Это процедура для паевых фондов. В базе идет работа с несколькими фондами одновременно, а баланс нужен по каждому.Т.о. @fond - это код паевого фонда, а @bln - тип баланса(денежный, депо, паевой) 2. AccState - остатки и обороты по счетам; запись появляется если есть движение за этот день по счету Аcc - просто лицевые счета PlnSub - субсчета(более верхний уровень для Acc) А вообще это сделано для HTML, там еще считается count(*) для rowspan. Выводить сразу остатки по лицевым счетам с группировками по разделам и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2001, 06:44 |
|
||
|
Оборотная ведомость
|
|||
|---|---|---|---|
|
#18+
Меня, вообще то не интересовал внутренний запрос, он и так работает шустро! Медленно (относительно) работает внешний! Спасибо за урок! Больше не буду кидать всю SP... Надо выделять суть. Интересен внешний запрос: Как к дереву прикрутить остатки? select Счет, Описание, sum(СуммаД), sum(СуммаК) ... from ПланСчетов "plan" left join ( ххххх ) oborotka on oborotka.Счет like rtrim(plan.Счет)+'%' --------------------------------------- Маленький пример: Счета Наименование Сумма ... 10 Материалы 10000 ... 10/1 Материалы 5000 ... 10/3 Топливо 3000 ... 10/5 Запчасти 2000 ... 10/5/1 Запчасти к БО 1500 ... 10/5/2 Запчасти к а/т 500 ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2001, 15:09 |
|
||
|
Оборотная ведомость
|
|||
|---|---|---|---|
|
#18+
Если Вы всё же посмотрите что я написал, то заметите что у меня нет outer join-ов(я так понял, что Вы это подразумеваете под термином "внешний запрос"). Принцип такой. Есть некая таблица create table #p( acc varchar(30), -- счет si dec(19,6), -- сальдо входящее (In) d dec(19,6), -- дебет c dec(19,6), -- кредит so dec(19,6)) -- сальдо исходящее (Out) Сначала туда вносятся входящие остатки по счету, остальные значения нули, потом обороты и потом исходщие остатки. Т.е. примерно так insert #p select acc, s,0,0,0 from .... insert #p select acc, 0,d,c,0 from .... insert #p select acc, 0,0,0,s from .... А потом значения из этой таблицы переносятся в другую, но уже с группировкой(у меня там несколько сложнее - еще разбивается на актив и пассив): insert #t select acc, sum(si),sum(d),sum(c),sum(so) from #p group by acc Вообщем: пишите попроще и будет быстрее работать, и самому понятней, и "люди к Вам потянуться" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2001, 06:12 |
|
||
|
Оборотная ведомость
|
|||
|---|---|---|---|
|
#18+
Опять мы не про то !... Сама Оборотка находится просто и мгновенно. И не важно как одним запросом или 3-4 с использованием врем.таблиц. (зря я ее кинул в 1 вопросе) Вопрос не в этом! Надо к плану счетов (дереву) присоединить оборотку, и рассчитать остатки на счетах верхнего уровня, типа: на счете 10: 10000 = 5000 + 3000 + 1500 + 500 (10/1 + 10/3 + 10/5/1 + 10/5/2) на счете 10/5: 2000 = 1500 + 500 (10/5/1 + 10/5/2) В моем (1) "огромном" запросе медленно работает объединение Плана счетов с обороткой ------ on об.Счет like rtrim(plan.Счет)+'%' -------- !!! ( join быстро работает когда on а.Acc=b.Acc, а не Like ) Итак: По Вашему совету я разбил свою SP как в последнем ответе и после последнего Insert #t select acc, sum(si),sum(d),sum(c),sum(so) from #p group by acc 1) вариант (используя insert, update) insert into #t1 -- #t1 такая же как #t select Acc, NAMES, 0, 0, 0, 0 from ПланСчетов -- далее собираю si, d, c, so из #t на cчета более высокого уровня update #t1 set si = isnull((select sum(si) from #t where #t.Acc like rtrim(#t1.Acc)+'%'),0), d = isnull((select sum(D) from #t where #t.Acc like rtrim(#t1.Acc)+'%'),0), c = isnull((select sum(C) from #t where #t.Acc like rtrim(#t1.Acc)+'%'),0), so = isnull((select sum(so) from #t where #t.Acc like rtrim(#t1.Acc)+'%'),0) select * from #t1 order by Acc ~ 24 секунды (всего) /часть спишем на индексы, в Плане счетов 1956 счетов, максимум 8 уровней/ 2) вариант (используя объединение) select Acc, Names, sum(si), sum(d), sum(c), sum(so) from ПланСчетов left join #t on #t.Acc like rtrim(ПланСчетов.Acc)+'%' group by Acc, Names ~ 9 секунд (всего) Ни чего то я не выйграл!!!! Было то ~ 5-6 сек. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2001, 17:20 |
|
||
|
|

start [/forum/topic.php?fid=46&gotonew=1&tid=1826349]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
29ms |
get topic data: |
11ms |
get first new msg: |
6ms |
get forum data: |
3ms |
get page messages: |
50ms |
get tp. blocked users: |
2ms |
| others: | 211ms |
| total: | 342ms |

| 0 / 0 |
