dc_setscopearray() - dc_dbgoto() bug

This forum is for eXpress++ general support.
Post Reply
Message
Author
skiman
Posts: 1185
Joined: Thu Jan 28, 2010 1:22 am
Location: Sijsele, Belgium
Contact:

dc_setscopearray() - dc_dbgoto() bug

#1 Post by skiman »

Hi Roger,

dc_setscopearray() is a very powerfull tool to use. I use it quite a lot. Sometimes I encountered a problem with record position. I found that the dc_dbgoto() isn't working.

See the sample below, is can be used with any database and index if there are at least 100 records. Just change dbffile and ntxfile to the correct names.

dc_dbskip(0) is also doing something weird. However, this isn't used in my application.

Code: Select all

use dbffile alias customer new      
set index to ntxfile

for x = 1 to 100 step 3
	aadd(aRecords,x)
next
customer->(dc_setscopearray(aRecords))
customer->(dc_dbgotop())
wtf customer->(recno())   // 1
customer->(dc_dbskip(1))
wtf customer->(recno())   // 4
customer->(dc_dbskip(1)) 
wtf customer->(recno())   // 7
customer->(dc_dbgoto(31))
wtf " goto 31 " , customer->(recno())   // should be 31 but stays on 7
customer->(dc_dbskip(1)) 
wtf customer->(recno())   // 10
customer->(dc_dbskip(1)) 
wtf customer->(recno())   // 13
customer->(dc_dbskip(0)) 
wtf "skip 0 " , customer->(recno())   // last record in file, in my test record 129
customer->(dc_dbgoto(31))
wtf "goto 31 " , customer->(recno())   // should be 31 but stays on 129.
customer->(dc_dbgobottom())
wtf "bottom" , customer->(recno())   // 100 

I hope you can find the solution for this.
Best regards,

Chris.
www.aboservice.be

User avatar
rdonnay
Site Admin
Posts: 4729
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: dc_setscopearray() - dc_dbgoto() bug

#2 Post by rdonnay »

Chris -

Have you tried dbGoto() insted of DC_DbGoTo().

I think I recall that DC_DbGoTo() was designed to disallow selection of a record that is not in scope.

Record 31 would not be in the scope array.

Roger
The eXpress train is coming - and it has more cars.

skiman
Posts: 1185
Joined: Thu Jan 28, 2010 1:22 am
Location: Sijsele, Belgium
Contact:

Re: dc_setscopearray() - dc_dbgoto() bug

#3 Post by skiman »

Hi Roger,

Record 31 is in the array, it is on position 11. Since it starts with 1, next are 4,7,10,...,31,34,...

dbgoto() is working, but the next dc_dbskip(1) isn't correct after a dbgoto(). The dc_dbskip(1) skips to the next element in the array.

Code: Select all

dc_dbgotop()  -> element 1, record 1
dbgoto(31) -> record 31
dc_dbskip(1) -> element 2, record 4.
I suppose that dc_dbgoto(31) should position the pointer to the correct array element. This is the only way a dc_dbskip(1) or dc_dbskip(-1) can work correct afterwards?
Best regards,

Chris.
www.aboservice.be

User avatar
rdonnay
Site Admin
Posts: 4729
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: dc_setscopearray() - dc_dbgoto() bug

#4 Post by rdonnay »

Yes, you are correct.

I should fix that.

I'll send you a fix.
The eXpress train is coming - and it has more cars.

User avatar
rdonnay
Site Admin
Posts: 4729
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

Re: dc_setscopearray() - dc_dbgoto() bug

#5 Post by rdonnay »

Add a line of code to the DC_DbGoTo() function in _DCSCOPE.PRG as shown below.
Rebuild DCLIPX.DLL by running BUILD19_SL1.BAT.

This should fix it.

Code: Select all

FUNCTION DC_DbGoTo( nRecNo, xDataSource )

LOCAL cDataType := Valtype(xDataSource), aScopeArray, nPointer

IF xDataSource == NIL
  aScopeArray := DC_SetScopeArray()
  IF !Empty(aScopeArray)
    nPointer := AScan( aScopeArray, nRecNo )
    IF nPointer > 0
      DC_SetScopeArrayPointer(nPointer)
      _dbGoTo(nRecNo)   // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ENDIF
  ELSE
    _dbGoTo(nRecNo)
  ENDIF
ELSEIF cDataType == 'C'  // It's an alias
  aScopeArray := (xDataSource)->(DC_SetScopeArray())
  IF !Empty(aScopeArray)
    nPointer := AScan( aScopeArray, nRecNo )
    IF nPointer > 0
      (xDataSource)->(DC_SetScopeArrayPointer(nPointer))
    ENDIF
  ENDIF
ELSEIF cDataType == 'N'  // It's an ADS SQL cursor
  RETURN AdsGoToRecord( xDataSource, nRecNo )
ELSEIF cDataType == 'O'  // It's an SQLexpress cursor
  RETURN xDataSource:goTo(nRecNo)
ENDIF

RETURN nil
The eXpress train is coming - and it has more cars.

skiman
Posts: 1185
Joined: Thu Jan 28, 2010 1:22 am
Location: Sijsele, Belgium
Contact:

Re: dc_setscopearray() - dc_dbgoto() bug

#6 Post by skiman »

Fixed. :dance:
Best regards,

Chris.
www.aboservice.be

Post Reply