Остатки по складам при партионном учете
Select messages from
# through # FAQ
[/[Print]\]

-> Программирование в БЭСТ-4

#1: Остатки по складам при партионном учете Author: Плешивцев ЕвгенийLocation: Плешивцев Евгений PostPosted: 13 Sep 2007 15:42
    —
1. добрый день коллеги, в номенклатурном справочнике товаров есть замечательная кнопка [F10] - остатки товара по складам и в случае партионного учета, по партиям. Примерно так:

но вот, если партий много, то вычислить остаток товара на складе уже затруднение, нужно партии суммировать вручную.

Для облегчения разработана функция пользователя:
Code:
//-------------------------------------------------------
// Расчет и вывод на печать остатков по складам
// из номенклатурного справочника.
// Аналог [F10] в номенклатурном справочнике.
// свернуто по партиям

// вер. 1.0 от 12/09/07
// разработано для Б-4+ 12.01 harbour

// вызывается из номенклатурного справочника

Function user_ostat_nomspr()
Local cGrup:=''
Local cNNum:=''
Local cSclad:=''
Local aStru:={}
Local aBuf:={'',0}
Local cDataBase:=''
Local aMsg:={}
Local cName:=''
Local nSum_Kol:=0

Altd()

dbPush()
cGrup:=mlabel->Grup
cNNum:=mlabel->NNum
cName:=Alltrim(Mlabel->Name)+'; '+alltrim(mlabel->Marka)+'; '+alltrim(mlabel->Razmer)


// таблица UsDataBase для группировки кол-ва по складам
aAdd(aStru,{"Sclad","C",6,0})
aAdd(aStru,{"Kol"  ,"N",9,3})

  cDataBase:=TEMPFILE(GlobalTmpPath,"dbf")
  DBCreate(cDataBase,aStru)
  NetUse("UsDataBase",cDataBase)

// заполним таблицу UsDataBase
dbPush('mkart','mkart','Empty(mkart->partia)=.t.',{'Upper(Grup+NNum)', Upper(cGrup+cNNum)})
  mkart->(dbGoTop())
  if mkart->(!Eof())
    do while mkart->(!Eof())
          aBuf[1]:= mkart->Sclad
          aBuf[2]:= mkart->KolTek
          UsDataBase->(AddRec())
           UsDataBase->(Gather(aBuf))
          UsDataBase->(dbUnLock())
      mkart->(dbSkip())
    enddo
  endif
dbPop()

Sum UsDataBase->Kol to nSum_kol
// вывод на печать
aAdd(aMsg, 'Остатки товара '+cName)
aAdd(aMsg, '----------------------')
aAdd(aMsg, '| Склад  | Количество|')
aAdd(aMsg, '----------------------')
UsDataBase->(dbEval({|| aAdd(aMsg,'| '+UsDataBase->Sclad+' | '+str(UsDataBase->Kol,9,3)+' |')}))
aADD(aMsg, '----------------------')
aAdd(aMsg, '|Итого   | '+str(nSum_Kol,9,3)+' |')

View(aMsg)

UsDataBase->(dbCloseArea())
dbPop()

return nil


а вот результат работы:


а вызов функции я повесил на [Ctrl-F7]:


Last edited by Плешивцев Евгений on 13 Sep 2007 17:10; edited 1 time in total

#2:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 16:35
    —
Женя за текст спасибо но в картотеке для этого есть ALT_I

#3:  Author: BehemothLocation: Новиков Алексей Юрьевич PostPosted: 13 Sep 2007 16:39
    —
Странно, я всегда считал, что Alt-I - это иерархия.

#4:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 16:43
    —
Виноват CTRL-I

#5:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 16:44
    —
Кстати в номенклатурном справочнике не подписано но CTRL-I тоже
показывает суммарный остаток по номенклату

#6:  Author: Плешивцев ЕвгенийLocation: Плешивцев Евгений PostPosted: 13 Sep 2007 16:47
    —
Костя, наверное [Ctrl-I] остаток по суммарной карточке, кстати работает и из номенклатурного справочника. Однако показывает остатки одного склада.
Тут же задача такая - сеть розничных магазинов, т.е. склад 1, 2,3,4,5,6... Пришел ходовой товар на центральный склад - нужно быстро посмотреть у кого сколько на остатке, сравнить. Т.е. нужна общая картина. А [Ctrl-I] работает так:

#7:  Author: Плешивцев ЕвгенийLocation: Плешивцев Евгений PostPosted: 13 Sep 2007 16:49
    —
блин, ну и долго же я пишу ответы, даже смешно
... я не тормоз....

#8:  Author: BehemothLocation: Новиков Алексей Юрьевич PostPosted: 13 Sep 2007 16:55
    —
nordk wrote:
Кстати в номенклатурном справочнике не подписано но CTRL-I тоже показывает суммарный остаток по номенклатуре

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

#9:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 17:05
    —
Ну тогда отчет по номенклатуре по остатка и не указывать код скла

#10:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 17:09
    —
Вообще я что-то подобное делал для крупной розничной сети, тока остатки по фирме (т.е. по всем базам данных)
А вообще в розничной сети раскидывать так остатки это наверно
начало автоматизации. Надо учитывать местоположение магаина,
скорость продажи в каждом магазине (коэффициент обораичваемости
своя норма запаса), наличие аналогов, необходимость перебрасывать остаток с одного магазина на другой.
У меня для этого огромная система написана....
А хозяин мелкой розничной сети просил такую информацию, согласен
программка может кому-то пригодить

#11:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 17:12
    —
Женя не сочти вредным - сделай расчет по MDOCM.
Рассчитает быстро и точно. По картотеке бывает остаток "плывет".
Опасно доверять текущим остаткам картотеки.
По F10 в картотеке он имеет свойство пересчитывать

#12:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 17:14
    —
И еще рекомендации.
Пользуйся SETSCOPE()
Это рекомендация Сан Саныча.
В любой момент могут перестать поддерживать скоб в DBPUSH()
Т.е. поддерживать эту возможность никто не обещал и не
документировал

#13:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 17:16
    —
Behemoth wrote:
nordk wrote:
Кстати в номенклатурном справочнике не подписано но CTRL-I тоже показывает суммарный остаток по номенклатуре

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


У меня работает. SP 36

#14:  Author: Плешивцев ЕвгенийLocation: Плешивцев Евгений PostPosted: 13 Sep 2007 17:19
    —
Quote:
В любой момент могут перестать поддерживать скоб в DBPUSH()


этот день я обведу чОрным фламастером в календаре, придется переделывать дофига работающих утилит. По моему мнению конструкция
Quote:
dbPush()
dbPop()

довольно удобна и очень наглядна в исходном коде.

Более того, фрагмент моей программы (в самом конце):
Quote:
UsDataBase->(dbCloseArea())


наотрез не работает если не поставить эти операторные скобки.

#15:  Author: Титов АлександрLocation: Титов Александр Александрович PostPosted: 13 Sep 2007 17:35
    —
Плешивцев Евгений wrote:
Quote:
В любой момент могут перестать поддерживать скоб в DBPUSH()


этот день я обведу чОрным фламастером в календаре, придется переделывать дофига работающих утилит. По моему мнению конструкция
Quote:
dbPush()
dbPop()

довольно удобна и очень наглядна в исходном коде.

Эту проблему мы решили, поддержим Scope в DbPush.

#16:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 17:46
    —
Плешивцев Евгений wrote:
Более того, фрагмент моей программы (в самом конце):
Quote:
UsDataBase->(dbCloseArea())


наотрез не работает если не поставить эти операторные скобки.


А вот это непонят

#17:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 18:26
    —
Еще пару комментариев. Думаю это Вам не лишнее будет
Поскольку таблица временная - то ее можно открывать монопольно
и тогда DBUNLOCK() можно не делать.
При больших объемах данных быстрее работает DBEVAL()
чем цикл с перебором. (Труднее отлажива

#18:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 18:32
    —
Преобразую

Code:
mkart->(dbGoTop())
  if mkart->(!Eof())
    do while mkart->(!Eof())
          aBuf[1]:= mkart->Sclad
          aBuf[2]:= mkart->KolTek
          UsDataBase->(AddRec())
           UsDataBase->(Gather(aBuf))
          UsDataBase->(dbUnLock())
      mkart->(dbSkip())
    enddo
  endif


Code:
mkart->( DBEVAL({|aBuf|aBuf:={mkart->SCLAD,mkart->KolTek},;
                                      UsDataBase->( Addrec() ),                    ;
                                      UsDataBase->(Gather(aBuf))                 ;
                            }) )

#19:  Author: nordkLocation: Горбунов Константин PostPosted: 13 Sep 2007 18:35
    —
Но еще раз повторюсь - сделай по MDOCM будет надежнее и ничуть
не дольше (на глаз незаметно)

#20:  Author: Плешивцев ЕвгенийLocation: Плешивцев Евгений PostPosted: 14 Sep 2007 07:58
    —
Титов Александр wrote:
Эту проблему мы решили, поддержим Scope в DbPush.

добрый день, немного не понятно. dbPush() остается? Он будет дополнительно расширен и модифицирован?

#21:  Author: Плешивцев ЕвгенийLocation: Плешивцев Евгений PostPosted: 14 Sep 2007 08:03
    —
nordk wrote:
Но еще раз повторюсь - сделай по MDOCM будет надежнее и ничуть
не дольше (на глаз незаметно)

Костя, тут такое дело, согласен я с тобой. Но мещански (потребительски) считаю что если с движением порядок, то Компания БЭСТ позаботилась о корректности MKART->KolTek. Если же с движением проблемы / сбои то тут хоть через MDOCM, все равно мусор надо вычищать а картотеку по [F10] пересчитывать.

#22:  Author: nordkLocation: Горбунов Константин PostPosted: 14 Sep 2007 10:54
    —
Да DBPUSH() будет работать - это я оказывается владею
старыми инструкциями.
Что касается MDOCM, -то если делаете аналог по F10 - то он
работает по MDOCM. И это не вина разработчика.
Любое хранилище данных страдает подобными проблемами.
Просто если бы еще в программе было очень жесткое ожидание
блокировок даже, то никто бы не был застрахован от ошибки
связанной при работе на кривом индексе. Т.е. при работе в
сетевом режиме от этой проблемы на 100% застраховаться от пользовательских проблем нельзя, поэтому и написана задача пересчета остатков в картотеке, отсюда и моя рекомендация.
Вы же не хотите чтобы у Вас спрашивали почему у нас вчера
остаток правильно считался а сегодня он перестал считаться.
В итоге Вашей задаче перестанут доверя

#23:  Author: Плешивцев ЕвгенийLocation: Плешивцев Евгений PostPosted: 14 Sep 2007 11:47
    —
вот оптимизированный код, с учетом замечаний Константина. Так же учтены вопросы закрытия БД:
Code:
//-------------------------------------------------------
// Расчет и вывод на печать остатков по складам
// из номенклатурного справочника.
// Аналог [F10] в номенклатурном справочнике.
// свернуто по партиям

// вер. 1.1 от 12/09/07
// разработано для Б-4+ 12.01 harbour
// разработано для Кофе-тайм

// вызывается из номенклатурного справочника

// вер 1.1 - оптимизирован код

Function user_ostat_nomspr()
Local cGrup:=''
Local cNNum:=''
Local cSclad:=''
Local aStru:={}
Local aBuf:={'',0}
Local cDataBase:=''
Local aMsg:={}
Local cName:=''
Local nSum_Kol:=0
Local aSet:={}

Altd()
aSet=SaveSet()

cGrup:=mlabel->Grup
cNNum:=mlabel->NNum
cName:=Alltrim(Mlabel->Name)+'; '+alltrim(mlabel->Marka)+'; '+alltrim(mlabel->Razmer)


// таблица UsDataBase для группировки кол-ва по складам
aAdd(aStru,{"Sclad","C",6,0})
aAdd(aStru,{"Kol"  ,"N",9,3})

  cDataBase:=TEMPFILE(GlobalTmpPath,"dbf")
  DBCreate(cDataBase,aStru)
  Use &cDataBase Alias UsDataBase New EXCLUSIVE

// заполним таблицу UsDataBase
dbPush('mkart','mkart','Empty(mkart->partia)=.t.',;
       {'Upper(Grup+NNum)', Upper(cGrup+cNNum)})

mkart->(DBEVAL({|| aBuf:={mkart->SCLAD,mkart->KolTek},;
                          UsDataBase->( Addrec() ),;
                          UsDataBase->(Gather(aBuf))}))
dbPop()

Sum UsDataBase->Kol to nSum_kol
// вывод на печать
aAdd(aMsg, 'Остатки товара: '+cName)
aAdd(aMsg, '----------------------')
aAdd(aMsg, '| Склад  | Количество|')
aAdd(aMsg, '----------------------')
UsDataBase->(dbEval({|| aAdd(aMsg,'| '+UsDataBase->Sclad+' | '+str(UsDataBase->Kol,9,3)+' |')}))
aADD(aMsg, '----------------------')
aAdd(aMsg, '|Итого   | '+str(nSum_Kol,9,3)+' |')

View(aMsg)

UsDataBase->(dbClosearea())
RESTSET(aSet)

return nil



-> Программирование в БЭСТ-4


output generated using printer-friendly topic mod. All times are GMT + 4 Hours

Page 1 of 1

Powered by phpBB © 2001, 2005 phpBB Group