View previous topic :: View next topic |
Author |
Message |
PiSoft
Joined: 25 Mar 2005 Posts: 17 Location: ПЕТРОВ Олег Алексеевич Occupation: ООО ПЕТРОПЕН Плюс, сист. прогр. Interests: СПб
|
Posted: 11 Aug 2005 15:10 Post subject: Проблема с SetScope |
|
|
Подскажите, пожалуйста, в чем тонкость.
Есть прога, вызываемая из реестра накладных по F5, следующего содержания:
PRIVATE cLoadPath,cScopeStr
dbPush()
cLoadPath:=loadpath()
cScopeStr:=MDOC->(UPPER(sclad+vid+type+DTOS(date)+codedoc+numdoc))
dbPush()
NetUse("pDoc",cLoadPath+"Sclad\pDoc.dbf")
pDoc->(ORDSetFocus("MDOC_D"))
pDoc->(SetScope())
pDoc->(dbGoTop())
// Удалим предыдушие записи в pDOC, если они были
pDoc->(SetScope("UPPER(sclad+vid+type+DTOS(date)+codedoc+numdoc)",cScopeStr))
pDoc->(dbGoTop())
while(pDoc->(!eof()))
pDoc->(RecLock())
pDoc->(dbDelete())
pDoc->(f_dbUnLock())
pDoc->(dbskip())
enddo
pDoc->(SetScope())
pDoc->(dbGoTop())
// Добавим новые
pDoc->(addrec())
............
pDoc->(f_dbunlock())
pDoc->(dbCloseArea())
dbPop()
dbPop()
Ее цель - скопировать помеченные документы в таблицу (копия MDOC) для дальнейшей обработки, удалив предварительно уже имеющиеся записи по этим документам. Документы имеют номера типа 100s1, 100s2... и т.д.
Если метить документы по возрастанию номеров, все работает ОК. Но если порядок произвольный, то удаляются все записи с большими номерами выбранные до меньших номеров Т.е. создается впечатление, что SetScope не работает как фильтр "=", хотя указан только один параметр в диапазоне.
В чем может быть проблема? |
|
Back to top |
|
|
nordk
Joined: 27 Jun 2005 Posts: 1000 Location: Горбунов Константин Occupation: БЭСТ-Партнер Interests: СПб
|
Posted: 11 Aug 2005 21:00 Post subject: |
|
|
Честно говоря не понятно что Вы делаете.
Где вы записи удаляете в аналоге MDOC или MDOCM ?
Если в MDOC - то запись одна, если в mdocm - то при чем здесь индекс MDOC_D и скоп по нему. Для mdocm нужно накладывать скоп по его индексам и по нему идти, а для mdoc скоп вообще не нужно - нашел сиком и удалил..... Даже искать не надо - вы уже стоите на помеченном вообщето
И вообще у нас в Питере телефон есть - можно позвонить, думаю что мне все равно где отвечать на форуме или по телефону |
|
Back to top |
|
|
Krosh
Joined: 13 Oct 2003 Posts: 97 Location: КИА Occupation: СТ Interests: Москва
|
Posted: 12 Aug 2005 09:18 Post subject: |
|
|
Скорее проблема не с SetScope, а проблема перед монитором.
Спец ф-ция выполняется для отмеченных строк в реестре, т.е. для КАЖДОГО документа.
Scope для того, чтобы удалить ЕДИНСТВЕННЫЙ (ТЕКУЩИЙ) документ не нужен.
Что мешает без всякого Scope поиском DBSEEK встать на нужную строку и удалить её? |
|
Back to top |
|
|
PiSoft
Joined: 25 Mar 2005 Posts: 17 Location: ПЕТРОВ Олег Алексеевич Occupation: ООО ПЕТРОПЕН Плюс, сист. прогр. Interests: СПб
|
Posted: 12 Aug 2005 10:30 Post subject: |
|
|
nordk wrote: | Честно говоря не понятно что Вы делаете.
Где вы записи удаляете в аналоге MDOC или MDOCM ?
Если в MDOC - то запись одна, если в mdocm - то при чем здесь индекс MDOC_D и скоп по нему. Для mdocm нужно накладывать скоп по его индексам и по нему идти, а для mdoc скоп вообще не нужно - нашел сиком и удалил..... Даже искать не надо - вы уже стоите на помеченном вообщето
И вообще у нас в Питере телефон есть - можно позвонить, думаю что мне все равно где отвечать на форуме или по телефону |
Спасибо за дельные советы, но я хотел бы получить ответ на заданный вопрос. Я привел только маленький фрагмент текста программы, которая работает с MDOC, и с MDOCM (кстати на его аналоге происходит то же самое), и с MAIN. В моем pDoc (аналоге MDOC) собираются документы из одинаковых, но не связанных баз, и в общем случае, имеют несколько "одинаковых" документов, на основании которых формируется в pDoc один необходимый, а остальные удаляются.
Если Вас коробит SetScope по отношению к аналогу MDOC, то с аналогом MDOCM ситуация аналогична. А уж там с "сиком" делать нечего
Так вот, я спрашиваю: почему в данном случае SetScope работает не по "=", а по ">="?
А по телефону обсуждать чужую программу не очень-то удобно |
|
Back to top |
|
|
nordk
Joined: 27 Jun 2005 Posts: 1000 Location: Горбунов Константин Occupation: БЭСТ-Партнер Interests: СПб
|
Posted: 12 Aug 2005 13:08 Post subject: |
|
|
В данном случае надо полагать он вообще НЕ РАБОТАЕТ ТАК КАК ВЫ ЭТО СЕБЕ ПРЕДСТАВЛЯЕТЕ. НЕЛЬЗЯ УДАЛЯТЬ ЗАГОЛОВКИ НЕ УДАЛЯЯ СТРОК ДОКУМЕНТА. НЕЛЬЗЯ УДАЛЯТЬ СТРОКИ ПО СКОПУ НА ЗАГОЛОВОК А НЕ НА СТРОКИ...
Setscope прекрасно работает при его правильном применении - т.е. вы корректно на текущий индекс (или нужный индекс) установили скоп.
Проблемы возникают когда ключ скопа не совпадает со старшей частью ключа индекса или в процессе корректировки вы изменили значение поле попадающее в ключ скопа. Но это правильно не проблемы - а аккурастность применения данной функции.
А так SETSCOPE намного лучше чем какие-то фильтры.
МОжно сказать весь БЭСТ построен на этой функции - так что она не может не работать...Детально это уже на примерах надо...
Чужая программа нас не интересует - у нас своих полно
Совет: пройдите программой через отладчик HArbour и надеюсь сможете понять свои ошибки в программирован
Last edited by nordk on 12 Aug 2005 13:12; edited 1 time in total |
|
Back to top |
|
|
Krosh
Joined: 13 Oct 2003 Posts: 97 Location: КИА Occupation: СТ Interests: Москва
|
Posted: 12 Aug 2005 13:11 Post subject: |
|
|
1.
PiSoft wrote: | А уж там с "сиком" делать нечего |
Есть!
Часто в MDOCM удобно найти начало документа поиском (DBSEEK), а потом просто пройти по документу (вот тут можно и SCOPE использовать и цикл с проверкой "конца" документа).
2.
Может это ответ на непонятный вопрос?
Quote: |
SetScope()
SetScope(cScope,xScope,xScope1,aOrder) - задание ключевого интервального фильтра
SetScope() – отмена фильтра.
cScope - выражение для ключевой фильтрации в виде символьной строки для вычисления (путем макроподстановки) значения ключа при фильтрации.
XScope - значение ключа для ключевой фильтрации, т.е. уставливается фильтр. &(cScope)==xScope для ключа или значение нижней границы ключа, если xScope1!=NIL
xScope1 - значение верхней границы ключа,если xScope1!=NIL, то устанавливается фильтр на интервал: xScope...xScope1
aOrder - массив ордеров, на которые распространяется SetScope, NIL - все.
{'TAG_NNDOC'} - первый и т.д.
lAdd - если .T., то осуществляется добавление к текущему SetScope(), используется для установки различных граничных условий по различным tag'ам.
При применении ключевой фильтрации следует следить, чтобы при любом tag'е, который может выбрать пользователь, выражение cScope являлось старшей частью ключа.
Пример:
FUNCTION DoSV
PRIVATE aScopeSent,aScopeVal,nScopePointer
EvalFun("ScopeStepForward")
RETURN
UNCTION ScopeStepForward
IIf((nScopePointer<3),DOC51->(SetScope(aScopeSent[nScopePointer+1],aScopeVal[nScopePointer+1])))
RETURN
.......................
aAllDoc->(setScope("Scladcode",aSclad->ScladCode))
|
|
|
Back to top |
|
|
PiSoft
Joined: 25 Mar 2005 Posts: 17 Location: ПЕТРОВ Олег Алексеевич Occupation: ООО ПЕТРОПЕН Плюс, сист. прогр. Interests: СПб
|
Posted: 12 Aug 2005 14:03 Post subject: |
|
|
nordk wrote: | В данном случае надо полагать он вообще НЕ РАБОТАЕТ ТАК КАК ВЫ ЭТО СЕБЕ ПРЕДСТАВЛЯЕТЕ
...
А так SETSCOPE намного лучше чем какие-то фильтры.
...
Детально это уже на примерах надо
...
Совет: пройдите программой через отладчик HArbour и надеюсь сможете понять свои ошибки в программировании |
Вы правы, не работает он так, КАК Я ПРЕДСТАВЛЯЮ . А при замене SetScope на такую же строку dbSetFilter - работает.
Но SetScope же НАМНОГО ЛУЧШЕ , поэтому я и решил его использовать, ИЗУЧИВ ПРИМЕРЫ из БЭСТа.
Именно с помощью отладчика я понял, что он выбирает строки с ключевым выражением > указанного.
Но ПОЧЕМУ? |
|
Back to top |
|
|
nordk
Joined: 27 Jun 2005 Posts: 1000 Location: Горбунов Константин Occupation: БЭСТ-Партнер Interests: СПб
|
Posted: 12 Aug 2005 15:59 Post subject: |
|
|
У меня есть серъезное подозрение что он ничего не выбирает а Вы идете по какому-то непонятному алгоритму. В указанном Вами примере он не должен работать - он и не работает. Цепочку же событий вы приписываете работе функции.....
И это не фильтр !!!! Это скоп - фильтр всегда будет работать значительно медленнее...
Если вам интересно - напишите пример простенький типа пары БД MDOC и MDOCM и индексов по которым хотите прогуляться
Я вам напишу пример как надо применять или загляните в офис к нам я на своей программе наглядно покажу как это работать должно в том же MDOC-MDOCM |
|
Back to top |
|
|
PiSoft
Joined: 25 Mar 2005 Posts: 17 Location: ПЕТРОВ Олег Алексеевич Occupation: ООО ПЕТРОПЕН Плюс, сист. прогр. Interests: СПб
|
Posted: 12 Aug 2005 17:05 Post subject: |
|
|
nordk wrote: | В указанном Вами примере он не должен работать - он и не работает. |
Извините за назойливость, но:
У меня есть реестр документов MDOC.dbf, в котором имеется ключ MDOC_D с индексным выражением UPPER(sclad+vid+type+DTOS(date)+codedoc+numdoc)+"999 ". Стоя на конкретной записи этого реестра, я формирую значение головной части ключа cScopeStr:=MDOC->(UPPER(sclad+vid+type+DTOS(date)+codedoc+numdoc)).
Открываю вспомогательную таблицу PDOC.dbf - аналог MDOC.dbf, но возможно, с повторяющимися записями, т.к. она формируется простым добавлением записей из других баз. Устанавливаю текущим ключ MDOC_D и скоп pDoc->(SetScope("UPPER(sclad+vid+type+DTOS(date)+codedoc+numdoc)",cScopeStr)), чтобы удалить записи, совпадающие по UPPER(sclad+vid+type+DTOS(date)+codedoc+numdoc с текущей записью MDOC.dbf
Так почему "он не должен работать"? Скажите конкретн |
|
Back to top |
|
|
nordk
Joined: 27 Jun 2005 Posts: 1000 Location: Горбунов Константин Occupation: БЭСТ-Партнер Interests: СПб
|
Posted: 12 Aug 2005 17:28 Post subject: |
|
|
Ну чтож давайте разбираться.
1. Удалять хотите в pDOC
Значит по файлу pDoc у нас должен быть pDoc.cdx с тагом MDOC_d
2. По файлу pDoc надо установить что на нем индекс именно MDOC_d
То есть pDoc->( ORDSETFOCUS('MDOC_D') )
Здесь временно я бы вставил SayAndWait(pDoc->(Indexkey())) для просмотра что именно такой ключ
а затем SayAndWait(cScopeStr) и убедительс что они подходят друг другу и главное именно от того документа на котором стояли в момент входа в Вашу программу
3. Далее pDoc->( SETSCOPE("(UPPER(.....)",cScopeStr,,{"MDOC_D"}) )
4. pDoc->( DBGOTOP() )
5. В цикле удаляем
WHILE pDoc->( RECNO() )<pDOC->( LASTREC() )+1 - я так люблю лично
возможно WHILE !pDoc(EOF()) но не WHILE(!pDoc(EOF()) хотя может этот WHILE и работает но мы имеем дело с FileEval
и вообще я в FileEval EOF() не очень доверяю - пример не приведу, но вроде как бывало подводил
Хотя запись в MDOC всего одна и нам этот WHILE по барабану
Если FileEval
pDoc->( RECLOCK() )
pDoc->( DBDELETE() )
pDoc->( F_DBUNLOCK() )
pDoc->( DBSKIP() )
Если HFileEval
pDoc->(xDelete())
ENDDO
Концовка понятна
У вас вроде все похоже стоит,тока не работает
Лично у меня такая схема работает хоть вкривь метьте хоть вкось
А да кстати где у вас pDoc->( DBCOMMIT() ) ?
ну и наконец когда совсем непонятно добавьте в начало проги aSet:=SaveSet()
а в конец RestSet(aSet) а сам cScopeStr (его значение) в aPars[1]
а DBPUSH() и DBPOP() можно убрать
Но вообще забавно действие в одну строку превратили в такое что не сразу и поймешь зачем это
Кстати чтобы было понятно метка работает так - в массив заносятся номера физических записей MDOC и соответственно он встает точно на номер без индекса а вот если в pDoc индекс будет кривой то....тут увы функция не виновата Вот и все....у меня работает
Last edited by nordk on 12 Aug 2005 18:12; edited 1 time in total |
|
Back to top |
|
|
PiSoft
Joined: 25 Mar 2005 Posts: 17 Location: ПЕТРОВ Олег Алексеевич Occupation: ООО ПЕТРОПЕН Плюс, сист. прогр. Interests: СПб
|
Posted: 12 Aug 2005 18:05 Post subject: |
|
|
Спасибо большое!
Вот теперь есть повод для движения вперед , а то застрял и не знаю как же это - все говорят "SetScope - это здорово", а у меня не прет, и мыслей больше никаких
Буду пробовать ",,{"MDOC_D"}", разные EVALы и контрольный вывод.
Хорошей погоды |
|
Back to top |
|
|
nordk
Joined: 27 Jun 2005 Posts: 1000 Location: Горбунов Константин Occupation: БЭСТ-Партнер Interests: СПб
|
Posted: 12 Aug 2005 18:13 Post subject: |
|
|
{'MDOC-D'} это не то - его можно было и не указывать - тогда скоп на все индексы встает |
|
Back to top |
|
|
|