Добрый день,
Хочу написать не сложный код на Б4+ (12.01 SP45) АРМ склад.
Задача такая: у нас есть фас.цех где часть товара фасуют в мелкую тару, при этом товар заносится в другую группу и соответственно номенклатурный номер.
Может я чего не знаю но возможности сделать так чтобы расход был одних товаров, а приход других (по типу внутреннего перемещения) я не нашел. Решил сделать сам. такая:
- на складе фасцеха "реализация" делается новая операция типа перемещение фасованых товаров.
- по событию на запись должены появиться 2 InitList() 1 - со списком товаров из накладной, а 2 - со списком товаров который надо привязать к каждой позиции первого списка.
- из второго списока будет будет создана порожденная приходная накладная.
Ну и поле для связи между строками надо какое-то например Oper_fact подойдет.
Собственно я так думаю сделать.
Вообще смысл всего этого такой - выявить излишки или недостачу на фасцехе, пока это делается вручную...
Теперь ы:
-Может есть что-то стандартное.
-Ну и про 2 инитлиста прошерстил весь форум хотел примерчик найти, но не нашел видел только что ссылаются на Урок 8 но сам урок не нашел.
Добрый день!
Там пример про два инитлиста на экране, одновременно.
Возможно подойдет для этого случая.
Но я бы хотел обратить на первичность использования стандартных средств.
Т.е. в этом случае можно делать не внутреннее перемещение, а списание на фасовку, скажем. и порождать автоматом накладную на приход другой позиции.
Список привязки оформить как таблицу пользователя, это по сути спецификация.
И уже по ней в коде формировать новую накладную.
Как вариант, возможно затраты по кодингу здесь будут меньше и надежнее.
Не надо каждый раз делать привязку, если я правильно понял задачу.
Получится примерно такой набор "внедрений":
- таблица привязки (списываемый = приходуемый)
- настройки в реестрах движения, возможно новый реестр, для удобства
- плагин на событие (обработка накладной и формирование новой)
- плагин для реестра на таблицу привязки
itman пишет:
Добрый день!
...
Т.е. в этом случае можно делать не внутреннее перемещение, а списание на фасовку, скажем. и порождать автоматом накладную на приход другой позиции.
Списко привязки оформить как таблицу пользователя, это по сути спецификация.
И уже по ней в коде формировать новую накладную.
Как вариант, возможно затраты по кодингу здесь будут меньше и надежнее.
Не надо каждый раз делать привязку, если я правильно понял задачу.
Спасибо, я примерно так и думал только связанную накладную хочу формировать сразу после записи расхода с фасцеха. Для этого и надо 2 инитлиста, так как 1-ой позиции списания могут соответствовать несколько позиций в порожденной накладной(разная фасовка).
Для связи думаю использовать поле oper_fact из mdocm и поля CodeDoc1 и NameDoc1 из mdoc + временная таблица.
Можно взять инструментарий для БЭСТ-4, и разобраться в нем.
Там непосредственно основные функции БЭСТа в исходниках.
А по поводу задачи, есть ли строгое соответствие для фасовок?
Существует же определенное количество вариантов, нельзя ли их идентифицировать?
Просто в использовании 2 инитлиста будет не очень удобно и отнимет время оператора.
Для оператора чем проще тем лучше, ему легче выбрать из предложенного чем ввести.
В последнее время я в этом все чаще и чаще убеждаюсь, цепочка вопросов и действие алгоритма в зависимости от ответов позволяют свести ошибки оператора к минимуму (но могут добавить ошибки кода ).
И я бы не рекомендовал использовать oper_fact, равно как и любое другое поле.
Сделайте свое поле по правилам БЭСТ-4, свой индекс. описания полей есть в системе.
Строгого соответствия нет, более того один и тотже товар(мы торгуем химикатами) зачастую имеет много наименований (синонимов)и часто в одной группе(нефасованый) он называется "аммоний двухромовокислый" а в другой(фасованый) "аммоний бихромат" а по факту это одно и тоже. Поэтому планирую просто выбирать из справочника mlabel а партию формировать автоматом иначе никак. Про свои поля я в курсе, пользуюсь уже просто хотел как проще.
А про библиотеку функций, я имел ввиду пользовательские(мои), у меня уже более 10 плагинов и многие из них используют одни и теже функции, мне их приходится в исходники дописывать ну и при изменениях приходится их заново переписывать и т.д. Или библиотеки можно только на харборе сделать? я не пробовал.
Да либо полный путь указывать либо рядом положить.
Думаю удобнее сделать свою папку и указывать полный путь на нее - а там хранить библиотеку,которую будете пристыковывать. (Или библиотеки)
Здравствуйте, Мучаюсь с двумя инитлистами - не получается.
видно что-то не так, может подскажите.
вот что у меня получилось в соответствии с уроком 8
срабатывает на событие "Проверка документа"
Код
Function u2Init()
Local cInsDB1, cInsDB2, cInsIdx, aInsStru, I, N
Local aSet, aSetKey
Private aRef, aSortSeek1,cGr, _numrec:=1
aSet:=SAVESET()
aSetKey:=SaveSetKey()
// создаем временную таблицу
cInsDBF1 := TempFile(m->GlobalTmpPath,"DBF")
cInsDBF2 := TempFile(m->GlobalTmpPath,"DBF")
aInsStru := {{'GRUP','C',5,0},{'NNUM','C',13,0},{'PARTIA','C',5,0},{'NAME','C',35,0},{'ED','C',5,0},{'KOL','N',19,4},{'CENA','N',19,2},{"LINK","N",17,0},{"COLOR","N",1,0}}
DbCreate(cInsDBF1,aInsStru)
NetUseExc('TMC1',cInsDBF1)
DbCreate(cInsDBF2,aInsStru)
NetUseExc('TMC2',cInsDBF2)
TMC2->( ORDCREATE(cInsIdx,'TMC_LINK','LINK',{||Link}) )
N = GetKolMat()
For I = 1 To N
TMC1->(ADDREC())
TMC1->GRUP:= GetMat(I,79, 5)
TMC1->NNUM:= GetMat(I,84, 13)
TMC1->PARTIA:= GetMat(I,405, 5)
TMC1->NAME:= GetMat(I,1, 35)
TMC1->KOL:= GetMat(I,36, 14,.T.)
TMC1->CENA:= GetMat(I,64, 15,.T.)
TMC1->LINK:=IncStep("OPERSTRFAC") //NNOPER для сdzpb
Next
TMC1->( F_DBUNLOCK() )
TMC1->( DbCommit() )
TMC1->(DbGoTop())
// initlist's
//задание параметров первой прямоугольной области
DispBox(2,0,15,79,( Chr( 201 ) + Chr( 205 ) + Chr( 187 ) + Chr( 186 ) + Chr( 188 ) + Chr( 205 ) + Chr( 200 ) + Chr( 186 )+' ' ) ,"W+/B")
//задание параметров второй прямоугольной области
DispBox(15,0,23,79,( Chr( 204 ) + Chr( 205 ) + Chr( 185 ) + Chr( 186 ) + Chr( 188 ) + Chr( 205 ) + Chr( 200 ) + Chr( 186 )+' ' ) ,"W+/B")
mLabel->(OrdSetFocus('mLabel'))
//Справочник
aSortSeek1:={;
{"- по номеру ","Шифр ", {'GRUP','NNUM'},'UPPER(aIn[1]+aIn[2])',,,,'Mlabel'},;
{"- по наименованию","Наименование ", {'Grup','Name'},'UPPER(aIn[1], aIn[2])',,,,'MLab_St'};
}
mLabel->( MAKEREFER("sl","Номенклатурный справочник",1,{"Гр.","Шифр ","Наименование ","Ед.","Квал.","Фас.","Доп."},;
{1,1,15}, "n/w,w+/n",{"NNUM"},{"aIn[2]"},'UPPER(aIn[1]+aIn[2])',;
{{||Field->GRUP},{||Field->NNUM},{||Left(Field->NAME,25)},{||Field->ED },{||Left(Field->Marka,6)},{||Left(Field->RAZMER,6)},{||Left(Field->Sort,10)}};
,aSortSeek1,;
,,,,,{||mlabel->(SetScope('UPPER(Grup+NNUM)',Upper(aIn[1],aIn[2])))},,;
,,,,,,,,'cFind$UPPER(Name)'))
aRef:={,'SL'}
// Init1(.T.)
Do While INIT1(.T.).And.INIT2(.T.)
EndDo
// записываем
RestSetKey(aSetKey)
RESTSET(aSet)
Return NIL
Function INIT1(lFlag)
Private nTop,nBot,cColHead,aBlockCols,cCurProc,bDel,aHeads
Private bPreGet
Private hnrowact
altd()
nTop:=3
nBot:=10
//Заголовки над полями
cColHead:={"Наименование Колич. Цена LINK "}
сCurProc:={||MOVE1(lFlag,@hnRowAct,m->_numrec,RecNo())}
//Заголовки колонок реестра
aBlockCols:={;
{{||Left(Field->Name,25)},0},;
{{||Str(Field->kol,12,4)},26},;
{{||Str(Field->Cena,12,2)},43},;
{{||Str(Field->LINK,17)},58};
}
//Запрещение удаления в таблице
bDel:={||.F.}
//Комментарии
SHADOWBOX(Chr(24)+Chr(25)+" - перемещение, TAb - переключение",23,3,23,75,"W/B")
// вызов функции
TMC1->(InitList(nTop,nBot,cColHead,aBlockCols,сCurProc,,,,,,,,,,,,,,,,,,,,,,,,hnrowact))
Return LastKey()!=27
//Второй инитлист
Function INIT2(lFlag)
Private mTop,mBot,mLeft,dColHead,bBlockCols,dCurProc,cDel,bHeadsmLeft
Private cPreGet
Private rnRowAct
altd()
mTop:=15
mBot:=22
mLeft:=1
//Заголовки над полями
dColHead:={"Наименование Колич. Цена LINK "}
dCurProc:={||MOVE1(lFlag,@rnRowAct,m->_numrec,RecNo())}
//Заголовки колонок реестра
bBlockCols:={;
{{||Left(Field->Name,25)},0},;
{{||Str(Field->kol,12,4)},26},;
{{||Str(Field->Cena,12,2)},43},;
{{||Str(Field->LINK,17)},58};
}
//Запрещение удаления в таблице
cDel:={||.F.}
//Описание полей ввода
bHeads:={;
{"Группа...............:","GRUP"},;
{"Номенклатурный номер.:","NNUM"}}
SHADOWBOX(" F4 - Ввод новой F8 - Удаление ",23,3,23,75,"W/B")
TMC1->(InitList(nTop,nBot,cColHead,aBlockCols,сCurProc,bHeads,aRef,,,,,,,,,,,,,,,,,,,,rnRowAct))
Return LastKey()!=27
Function MOVE1(_xlActiv,hnRowAct,xRec,xRec1)
Local m1end, m1Ar
altd()
m1End:=2
m1Ar:=(TMC1)->( QScroll() )
hnRowAct:=m1Ar[6]
If LastKey()=9
(TMC1)->( QOFF() )
SetLastKey(0)
m1End:=0
Else
If xRec ==NIL.Or.xRec<>xRec1
Init2(.F.)
m->_numrec:=xRec1
EndIf
If _xlActiv
m1End:=2
Else
QOff()
m1End:=0
EndIf
EndIf
Return m1end
Function MOVE2(_lActiv,rnRowAct)
Local m2End,m2Ar
m2Ar:=(TMC2)->( QScroll() )
rnRowAct:=m2Ar[6]
If LastKey()=9.Or.!_lActiv
(TMC2)->( QOFF() )
SetLastKey(0)
m2End:=0
Else
m2End:=2
EndIf
Return m2End
Выпадает на строке
Код
m1Ar:=(TMC1)->( QScroll() )
переменная не существует.
И еще рисует заголовок инитлиста не сверху а строки на 3 ниже
Выловил много ошибок - вроде заработало но криво отображаетя вернее область инитлиста почему-то усекается по размеру активной части экрана перед нажатием F10,
как сэтим бороться?
Ну да вы все просто напросто ремаркой закрыли :))
Как оно вообще работает
Схема работы примерно такая:
у вас 2 функции которые отвечают за свой экран
Зайдя в первый экран вам надо прорисовать второй.
Разумеется второй средствами Initlist Вы прорисовывать не будете.
Для этого то вторая функция при флаге .F. должна уметь рисовать второй экран сама по ablockCols и сама рисовать заголовок и свой box. А обращаться к ней надо всякий раз как по первому экрану двигаем курсор то есть
в cCurProc первой. Ну а когда Вы по нажатию TAB в первом экране завершается работа первого InitList то Вы просто напросто запускаете втораую функцию с флагом .T. и по сути рисуете второй InitList и вот таким образом кртитесь в цикле, пока где-то не нажмут ESC или F10 если это надо.
А Вы весь механизм ремарками закрыли и разумеется он по этой схеме работать не сможет. И во второй функции вообще нет прорисовки экрана,
разобрался скобки блин, но легче не стало.
во первых сразу 2 не рисуются,
вовторых если шевельнуть курсором, то INIT2() мелькает пару секунд и БЭСТ вываливается в главное меню.