Ну конечно !!!!! Мой косяк
aIn внутри массива непоредственно самого пункта поиска !!!!
Т.е там может быть:
1. в случае поиска только по одному полю только один элемент массива aIn[1]
2 в случае одновременном поиске по двум и более элементам aIn[1],aIn[2] и т.д.( например по группе и номенкл. номеру)
Я правильно Вас понял?
gabov пишет:
Теперь при редактировании записи при открытии справочника партнеров курсор встает на первую запись в которой не заполнено краткое наименование партнера.
А чему собственно равно значение переменной ain[7] при открытии справочника ?
Вероятно она имеет пустое значение вот и находит первую пустую запись :)
2.Если это так ,то как правильно задать этот параметр?
3.В отладчике Бэста 4 возможно ли посмотреть значения массива aIn?
nordk пишет: это у вас не прокатит
asortseek создает собственный массив aIn и разумеется раз 2 строки там 2 элемента
в первой строке надо писать UPPER(aIn[1]), во второй UPPER(aIn[2])
1.Уже запутался.
Если я указываю как Вы рекомендовали ,т.е.
Цитата
Цитата
aSortSeek:={;
{"- по коду ",{"Шифр "}, {'CODE'},'UPPER(aIn[1])',,,,'FULLCODE'},;
{"- по наименованию",{"Наименование "}, {'SHORTNAME'},'UPPER(aIn[2])',,,,'FULLNAME'};
}
то при нажатии на F7 (поиск по коду) - проблем нет!!,
но если нажать на F7 (поиск по наименованию) то опять появляется ошибка :
"error base/1003 Переменная не существует : Name "
Если указать :
Цитата
aSortSeek:={;
{"- по коду ",{"Шифр "}, {'CODE'},'UPPER(aIn[1])',,,,'FULLCODE'},;
{"- по наименованию",{"Наименование "}, {'SHORTNAME'},'UPPER(aIn[1])',,,,'FULLNAME'};
}
то поиск работает как по коду ,так и по наименованию.Ошибок нет!!
: Я Вас не правильно понял??
2.Указал перед MAKEREFER _partner->(ordsetfocus("name"))
Теперь при редактировании записи при открытии справочника партнеров курсор встает на первую запись в которой не заполнено краткое наименование партнера.
Проблема не ушла!
nordk пишет:
не надо никакие номера искать- я честно так и не понял какой тег вы хотели :)
для Partner.dbf, ключевое значение которого равно UPPER(shortname) надо писать "name"
В описании MAKEREFER по поводу 28 параметра :
" nTag - номер тега, по которому производится Seek по cKeyVal" .
Вот я и пытался к нему обратиться по номеру. А оказывается надо обращаться по имени.
1. Тем не менее указав 28-й параметр как 'NAME' проблему все равно не решил!
2.Дополнительно добавил сортировку (11-й параметр) :
aSortSeek:={;
{"- по коду ",{"Шифр "}, {'CODE'},'UPPER(aIn[7])',,,,'FULLCODE'},;
{"- по наименованию",{"Наименование "}, {'SHORTNAME'},'UPPER(aIn[7])',,,,'FULLNAME'};
}
После чего при нажатии в справ.партнеров на F7 появляется диалоговое окно выбора поиска и при выборе или вводе любого значения и нажатии на enter вываливается ошибка : "Переполнение массива", а затем еще error base/1003 Переменная не существует : Name
Как с этим бороться? Может быть у этих двух проблем одна причина?
Текст плагина с дополнениями:
// Для автоматического расчета суммы при вводе добавим
aWhen:={,,,,,{||aIn[6]:=aIn[4]*aIn[5]},,.T.}
// формат ввода данных
aPic:={,,,,,"999999999.99",}
// Для решения а уникальности по индексу служит переменная
nUniMode=2
//
aRef:={,,,,,,"partners"}
aSortSeek:={;
{"- по коду ",{"Шифр "}, {'CODE'},'UPPER(aIn[7])',,,,'FULLCODE'},;
{"- по наименованию",{"Наименование "}, {'SHORTNAME'},'UPPER(aIn[7])',,,,'FULLNAME'};
}
cFindMacro:='cFind$UPPER(Name)'
//Переменные для возможности отметки нескольких записей
//MyRecs -массив в котором будут хранится отмеченные записи
bYesArray:={|x| IF(ValType(x)=='A',m->MyRecs:=x,m->myRecs)}
bYesReplArray:={|| FIELD->CODE }
bCoProc:={|| IIF(LastKey()==K_TAB, Keyb(K_ENTER), Nil) }
bYesNoRepl:={|x| .t.}
bPreDisp:={|x| m->MyRecs:={},nil}
_PARTNER->( MAKEREFER("PARTNERS","Справочник поставщиков",2 ,{" Код ","Наименование поставщика"," И Н Н "},{3,5,16}, ;
"n/w,w+/n",{"SHORTNAME"},{"aIn[7]"},"UPPER(aIn[7])",{{||FIELD->CODE},{||FIELD->SHORTNAME},{||FIELD->CODE_PR}},;
aSortSeek,,,,, ;
,bPreDisp,,,, ;
,,bCoProc,,, ;
,'cFind$UPPER(ShortName)','NAME',,,;
,bYesArray,,,, ;
,,,bYesReplArray,bYesNoRepl, ;
,,,,, ;
,'NAME',"UPPER(aIn[7])") )
gabov пишет:
как 2 ( значение взял из поля TAG_NOMER файла bases_00.dbf ).
Проблема не ушла .Где копать?
Не совсем точно изложил.
Значение поля TAG_NOMER файла bases_00.dbf для Partner.dbf, ключевое значение которого равно UPPER(shortname) ,т.е соответствует значению для поиска по ключу в нашем случае , равно "02".
Из описания MAKEREFER не понятно как его надо указывать :
то ли как номер по порядку ,т.е. в данном случае 2,
то ли - просто значение "02"
gabov пишет:
3 Если запустить плагин ,вызвать справочник партнеров и отметить в справочнике партнеров одну или несколько записей и сохранить результат( нажав или Enter или Tab) , то если снова вызвать справочник партнеров при вводе новой записи или
при редактировании любой другой записи ,то прежние отметки INSсохраняются.
А надо бы чтобы при вызове справочника партнеровв другой записи этих отметок не было.
Возможно ли такое?
Есть блок кода, который выполняется перед построением справочника.
В этом блоке кода вам просто надо обнулить ваш массив
Определил семнадцатый параметр как bPreDisp:={|x| m->MyRecs:={},nil}.
Проблема ушла!
Определил девятый параметр как "UPPER(aIn[7])"
При открытии справочника в процессе редактирования записи курсор все равно встает на первую запись в справочнике.
Дополнительно определил 28-й параметр " nTag - номер тега, по которому производится Seek по cKeyVal"
как 2 ( значение взял из поля TAG_NOMER файла bases_00.dbf ).
Проблема не ушла .Где копать?
// Для автоматического расчета суммы при вводе добавим
aWhen:={,,,,,{||aIn[6]:=aIn[4]*aIn[5]},,.T.}
// формат ввода данных
aPic:={,,,,,"999999999.99",}
// Для решения а уникальности по индексу служит переменная
nUniMode=2
//
aRef:={,,,,,,"partners"}
cFindMacro:='cFind$UPPER(Name)'
//Переменные для возможности отметки нескольких записей
//MyRecs -массив в котором будут хранится отмеченные записи
bYesArray:={|x| IF(ValType(x)=='A',m->MyRecs:=x,m->myRecs)}
bYesReplArray:={|| FIELD->CODE }
bCoProc:={|| IIF(LastKey()==K_TAB, Keyb(K_ENTER), Nil) }
bYesNoRepl:={|x| .t.}
_PARTNER->( MAKEREFER("PARTNERS","Справочник поставщиков",2 ,{" Код ","Наименование поставщика"," И Н Н "},{3,5,16}, ;
"n/w,w+/n",{"SHORTNAME"},{"aIn[7]"},,{{||FIELD->CODE},{||FIELD->SHORTNAME},{||FIELD->CODE_PR}},;
,,,,, ;
,,,,, ;
,,bCoProc,,, ;
,'cFind$UPPER(ShortName)',,,,;
,bYesArray,,,, ;
,,,bYesReplArray,bYesNoRepl, ;
,,,,, ;
,'NAME') )
altd()
1.Без параметра bCoProc:={|| IIF(LastKey()==K_TAB, Keyb(K_ENTER), Nil) } также все работает .
Просто этот параметр в данном случае необходим ,для того чтобы можно было переносить выбранные записи еще и при помощи клавиши TAB
Т.е. даже при отсутствущем bCoProc при пометки INS несколько записей и последующем нажатии на ENTER массив myRecs заполняется выбранными значениями.
Дополнительно добавил bYesNoRepl:={|x| .t.}.
Но не совсем понятно - как можно воспользовать этим параметром.
Если записать bYesNoRepl:={|x| .f.}.то INS просто для отметки текущей записи не работает.
Может быть он нужен для проверки ,текущего значения (значений) отмечаемой записи или контроля за уже отмеченными записями.
Но как тогда в блоке кода ее проверить?
2.Из описания MAKEREFER : "#DEFINE P_REPL 43 // Блок кода выполняемый при добавлении элемента в массив выбора (bYesArray)"
Как я его не "крутил" так и не понял для чего он нужен, и как заставить его работать? И нужен ли он вообще для данного случая?
3 Если запустить плагин ,вызвать справочник партнеров и отметить в справочнике партнеров одну или несколько записей и сохранить результат( нажав или Enter или Tab) , то если снова вызвать справочник партнеров при вводе новой записи или
при редактировании любой другой записи ,то прежние отметки INS сохраняются.
А надо бы чтобы при вызове справочника партнеров в другой записи этих отметок не было.
Возможно ли такое?
[QUOTE]nordk пишет:
myRecs объявите privat - справочник внутри у себя не может видеть Ваши локальные переменные.
А блоки кода при компиляции не проверяются на "видимость"
[/QUOTE]Объявил Private myRecs.
Все равно myRecs имеет значение Nil.
[QUOTE]nordk пишет:
· bYesArray - очень что Вы про него вычитали
Я когда вычитываю - думаю надо попробовать, а под рукой ничего нет полезного\
А когда надо - никогда не вспоминаю
Попробуйте вот что
создайте справочник на какое-нибудь поле ввода
и пропишите в нем вот так
bYesArray:={|x| IF(ValType(x)=='A',m->MyRecs:=x,m->myRecs)},
где myRecs - объявите такую переменную
И после возвращения из справочника посмотрите в отладчике что в ней лежит
Если у вас все получится - я обещаю порыть в исходниках как такой справочник вызвать просто по нажатию кнопки а не через режим
ввода/корректировки.
Главное даст он в справочнике по Ins отмечать или нет - если никакие больше параметры объявлять для
этого не надо -по идее все должно получиться[/QUOTE]
Здравствуйте!
Переписал плагин в таком виде :
[QUOTE]#include "inkey.ch"
Function Main()
LOCAL aSet,aSetKey,nTop,nBot,cColHead,aBlockCols,cCurproc,bDel,_aHeads,aWhen,aPic,nUniMode,nApp,aRef,cFindMacro
LOCAL aType,bYesArray,myRecs
aSet:=SAVESET()
aSetKey:=SAVESETKEY()
SayAndWait("OK")
NETUSE("work_1",LOADPATH()+"\real\work_1.dbf",,.F.)
work_1->(dbcreateindex(GlobalTmpPath+"DATE","dtos(TEK_DATA)"))
work_1->(ordsetfocus("DATE"))
NETUSE("_Partner",LoadPath()+"partner.dbf",,.F.)
DISPBOX(2,0,23,79,( CHR( 201 ) + CHR( 205 ) + CHR( 187 ) + CHR( 186 ) + CHR( 188 ) + CHR( 205 ) + CHR( 200 ) + CHR( 186 )+' ' ),"W+/B")
nTop:=3
nBot:=22
cColHead:={" Дата Номер НАИМЕНОВАНИЕ Кол-во Цена Сумма "}
cCurProc:={||"2"}
aBlockCols:={{{||FIELD->tek_data},0},{{||FIELD->tek_nomer},9},{{||FIELD->name},16},{{||STR(FIELD->kol,5)},33},{{||STR(FIELD->cena,12,2)},39},{{||STR(FIELD->summa,12,2)},52}}
bDel:={||.F.}
ALTD()
aType:={{'1','Услуги системного инженера'}, ;
{'2','Услуги по программированию'},;
{'3','Услуги консультанта '}, ;
{'4','Услуги по терминальной св.'}}
// Для автоматического расчета суммы при вводе добавим
aWhen:={,,,,,{||aIn[6]:=aIn[4]*aIn[5]},,.T.}
// формат ввода данных
aPic:={,,,,,"999999999.99",}
// Для решения Вопрос а уникальности по индексу служит переменная
nUniMode=2
//
aRef:={,,,,,,"partners"}
Архив с подготовленной БД прикрепил.( на примере демобазы)
В файл в файл dbase\real\bases_05.dbf добавлять ничего не нужно.
1.Если переменной bYesArray присвоить значение bYesArray:={|x| IF(ValType(x)=='A',m->MyRecs:=x,m->myRecs)}
то программа при нажатии F2 в поле"Наименование контрагента" ругается ,что переменная не определена.
Если убрать m->.то ругани нет. Почему ????????
2.Теперь в окне справочника партнеров появилась пустая крайняя слева колонка.
при выборе партнера с помощью enter проблем нет,но если нажать insert ,то пишет "неверный аргумент".
Видимо,надо что-то еше дописывать!
3.
[QUOTE]где myRecs - объявите такую переменную
И после возвращения из справочника посмотрите в отладчике что в ней лежит[/QUOTE]
_PARTNER->( MAKEREFER("PARTNERS","Справочник поставщиков",2 ,{" Код ","Наименование поставщика"," И Н Н "},{3,5,16}, ;
"n/w,w+/n",{"SHORTNAME"},{"aIn[7]"},"UPPER(aIn[7])",{{||FIELD->CODE},{||FIELD->SHORTNAME},{||FIELD->CODE_PR}},;
,,,,, ;
,,,,, ;
,,,,, ;
,'cFind$UPPER(ShortName)',,,,;
,,,,, ;
,,,,, ;
,,,,, ;
,'NAME') ) Не помогло.Теперь при редактировании записи и нажатие F2 курсор встает на любую запись по не понятному алгоритму.
Здравствуйте!
По описанию MAKEREFER() определил ,что cKeyValDisp - это 20 параметр.
тогда на его место вставляем выражение 'UPPER(aIn[7])'.
Переписал для удобства чтения по пять параметров в строке:
Цитата
_PARTNER->( MAKEREFER("PARTNERS","Справочник поставщиков",2 ,{" Код ","Наименование поставщика"," И Н Н "},{3,5,16}, ;
"n/w,w+/n",{"SHORTNAME"},{"aIn[7]"},,{{||FIELD->CODE},{||FIELD->SHORTNAME},{||FIELD->CODE_PR}},;
,,,,, ;
,,,,'UPPER(aIn[7])', ;
,,,,, ;
,'cFind$UPPER(ShortName)',,,,;
,,,,, ;
,,,,, ;
,,,,, ;
,'NAME') )
Но проблема не ушла!
Надо еще что-то менять или дополнять?
Посмотрел описание MakeRefer.
1.Параметр, отвечающий за поиск записи в справочнике при его открытии , больше всего подходит следующий :
Цитата
cKeyValDisp – выражение в виде символьной строки для вычисления (путем макроподстановки) ключа при поиске первой записи для отображения справочника (если не указано,то исп–ся cKeyVal);
Если это так,то как правильно написать это выражение?
2.Но вот обнаружил в описании :
Цитата
Выполняется после ключевого поиска !
· bYesArray – Блок кода доступа к массиву, куда вернем значения, если помечены несколько записей.
{|x| IF(ValType(x)=='A', aArray:=x, aArray ) }
Т.е. речь идет о том ,что может быть помечено несколько значений в справочнике.
Воспользоваться этой возможностью можно только через Initlist или еще каким-то способом?
// Для автоматического расчета суммы
aWhen:={,,,,,{||aIn[6]:=aIn[4]*aIn[5]},,.T.}
// формат ввода данных
aPic:={,,,,,"999999999.99",}
// Для решения а уникальности по индексу служит переменная
nUniMode=2
//
aRef:={,,{|x|ROTATEANDREADER(x,aType)},,,,"partners"}
cFindMacro:='cFind$UPPER(Name)'
bPreGet:={,,{|x,y,z|aIn[x]:=FIELD->Type},,,,}
//bPreGet:={|x,y,z|aIn[x]:=FIELD->VID}
altd()
_PARTNER->( MAKEREFER("PARTNERS","Справочник поставщиков",2 ,;
{" Код ","Наименование поставщика"," И Н Н "},;
{3,5,16}, "n/w,w+/n",{"SHORTNAME"},{"aIn[7]"},,;
{{||FIELD->CODE},{||FIELD->SHORTNAME},;
{||FIELD->CODE_PR}},,,,,,,,,,,,,,,,,'cFind$UPPER(ShortName)';
,,,,,,,,,,,,,,,,,,,,'NAME') )
Редактирую запись .в поле " наименование контрагента " стоит Торговый дом "ГУМ".
Нажимаю F2 выбираю из справ партнеров Фирма "Квант".
Теперь если из другой любой записи попытаться вызвать справочник партнеров, то при нажатии на F2
курсор в справочнике партнеров будет стоять на Фирма "Квант", а хотелось бы ,чтобы он стоял на партнере редактируемой записи.
Как исправить?
nordk пишет:
static означает что эта функция "видна" только внутри плагина
и исключает ошибку "пересечения" имен с функциями разработчика
Т.е. когда плагин завершит работу эта функция перестанет существовать для БЭСТа
Из вашего ответа следует, что желательно все свои функции внутри плагина начинать с static ?!
Теперь плагин запускается ,но при корректировки любой существующей записи
появляется сообщение " переменная не существует".
У Вас в "Пятом Уроке" написано :
"2. Для того чтобы подставляло нужное надо использовать параметр 26
Туда надо прописать
bPreGet:={|x,y,z|aIn[x]:=FIELD->VID}
Проблема обнаружилась в переменной bPreGet:
Если ее переписать так :
bPreGet:={,,{|x,y,z|aIn[x]:=FIELD->VID},,,,}
То это сообщение об ошибке не возникает.
Но при продолжении редактирования записи ( проходим все поля enter)
-когда курсор находится в поле "Введите номер документа" нажимаем enter,
то появляется сообщение " переменная не существует".
Проблема оказалась в переменной aRef:={,,{|x|ROTATEANDREADER(x,m->aType)},,,,"partners"}
Если убрать m->,то сообщение об ошибке не появляется.
Из урока я так и не понял : надо ли указывать m->aType или параметр m-> вообще не нужен?
Сейчас только что обратил внимание ,что поля VID нет. Есть поле TYPE, поэтому надо писать :
bPreGet:={,,{|x,y,z|aIn[x]:=FIELD->TYPE},,,,}
1.Проблема была ,как Вы и писали, в структуре dbf файла.
Просто пересоздал файл и проблема ушла.
Но осталась не ясность.
Когда я по Вашему совету третий подмассив массива aBlockCols заменил на {{||test(aType)},16} и добавил
static FUNCTION test(aType)
Local cRezult
ALTD()
cRezult:= IF(!EMPTY(FIELD->TYPE),aType[VAL(FIELD->TYPE),2],SPACE(25))
return cRezult
я ожидал ,что отладчик при пошаговом прохождении "войдет" в функцию static FUNCTION test(aType).
Но если оставить эту функцию без изменений,то тогда при пошаговом прохождении,когда курсор при встанет на
строку bPreGet,,,,aHotKey)), нажатие на F8 не приводит к изменению экрана (.т.е не отображается выполняемая текущая строка
в листинге плагина).Отладчик не позволяет увидеть ни переменных, ни строк кода .... .
Точка останова ALTD() в этой функции тоже ничего не дает. То есть не понятно зашел в эту функцию или нет.
Если переписать эту функцию :
static FUNCTION test(aType)
Local cRezult
SAYANDWAIT("TEST")
ALTD()
cRezult:= IF(!EMPTY(FIELD->TYPE),aType[VAL(FIELD->TYPE),2],SPACE(25))
SAYANDWAIT("TEST1")
return cRezult
То тогда можно хоть понять ,что после первого SAYANDWAIT("TEST")
возникают проблемы(после него выходит сообщение об ошибке ) , а SAYANDWAIT("TEST1") уже не отображается.
Т.е. получается тот же принцип отладки как и при использовании Fileeval() -только через SAYANDWAIT().
2.Для чего FUNCTION test(aType) объявляется как static ?
// Для автоматического расчета суммы при вводе добавим
aWhen:={,,,,,{||aIn[6]:=aIn[4]*aIn[5],.T.},}
// формат ввода данных
aPic:={,,,,,"999999999.99",}
// Для решения а уникальности по индексу служит переменная
nUniMode=2
//
aRef:={,,{|x|ROTATEANDREADER(x,m->aType)},,,,"partners"}
cFindMacro:='cFind$UPPER(Name)'
bPreGet:={|x,y,z|aIn[x]:=FIELD->VID}
altd()
_PARTNER->( MAKEREFER("PARTNERS","Справочник поставщиков",2 ,;
{" Код ","Наименование поставщика"," И Н Н "},;
{3,5,16}, "n/w,w+/n",{"SHORTNAME"},{"aIn[7]"},,;
{{||FIELD->CODE},{||FIELD->SHORTNAME},;
{||FIELD->CODE_PR}},,,,,,,,,,,,,,,,,'cFind$UPPER(ShortName)';
,,,,,,,,,,,,,,,,,,,,'NAME') )
Программа ругается на строку :
work->(INITLIST(nTop,nBot,cColHead,aBlockCols,cCurProc,;
_aHeads,aRef,aPic,aWhen,,;
nUniMode,bDel,,,,;
,,aGetBlock,,,;
,,cFindMacro,,, ;
bPreGet,,,,aHotKey))
"Переменная не существует".
При этом на экране отображаются только значения по колонке "ДАТА" и "НОМЕР"
Видимо , я из Урока не понял как нужно правильно было задать из массива aBlockCols
третий подмассив {{||IF(!EMPTY(FIELD->TYPE),aType[VAL(FIELD->TYPE),2],SPACE(25))},16}
А из связки MakeRefer() и QINPUT() все таки нельзя получить множественный выбор.
Кажется ,в описаниях MakeRefer() что-то "промелькивало краем уха" про эту возможность.
[QUOTE]nordk пишет:
Почему Insert - там пробелом отметка идет
[/QUOTE]Нажимаю "пробел". Ожидаю увидеть какую-то подсветку(метку) на отмеченной записи.
Но ничего не происходит.
Здравствуйте!
"Нарисовал" окно :
FUNCTION MyDate
Local _top:=4,_left:=13,_bot:=15,_right:=72
LOCAL aDataItems:={}, alSelect:={}
LOCAL _dataN:=ctod("01/01/2015"),_dataE:=ctod("31/01/2015"),_data:=ctod(''),i
i:=0
_data:=DTOC(_dataN)
aadd(aDataItems,_data)
While i<_dataE-_dataN
_data:=dtoc(ctod(_data)+1)
aadd(aDataItems,_data)
i++
enddo
_bot:=max(4,min(i,15))
alSelect:=afill(array(len(aDataItems)),.t.)
ALTD()
DISPBOX(_top-1,_left-1,_bot+1,_right+1,'╔═╗║══╚║ ',"N/BG")
SAYSCREEN(" ВЫБИРЕТЕ ОДНУ ИЛИ НЕСКОЛЬКО ДАТ ОПРИХОДОВАНИЯ ПРОДУКЦИИ",_top-1,_left+2)
RETURN ACHOICE(_top, _left, _bot,_right , aDataItems,alSelect)
А как получить множественность выбора значений из массива aDataItems ,. т..е отметку клавишей ins нескольких значений ?
Справочников будет 3 : справочник партнеров, и еще два справочника - в одном строк 15, во втором строк 30.
Нужно отметить какое-то кол-во записей в каждом из них . Ну а далее сохранить в массив и т.д. и т.п.
Цитата
nordk пишет:
ВОзможно БЭСТовский аналог achoice подойдет - там есть множественный выбор
"achoice" в Бэсте - это что такое ?
Нужно все это для Бэст4 и Бэст5.
Нужно из справочника выбрать несколько значений через отметку клавишей Insert.
Возможно ли это сделать при помощи функций MakeRefer() и QINPUT() или для этого нужно использовать Initlist() ?