FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour xbrowse / ADS failure
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
xbrowse / ADS failure
Posted: Sat Oct 24, 2015 11:07 PM

In another thread, we identified there is still a continuing problem with xBrowse and ADS.

When we open a browse and the dbf does not have an index opened, when going towards the end of the file, the pointer has an error. We have shown this consistently and it has also been previously reported by at least one other person. If an index is open, the error does not occur.

The previous threads on this topic were specific and the error was noted, but no fix has yet taken place.

The specific build uses FWH 15.09 xBrowse, Harbour, MSVC 2013, and ADS Server mode.

Can we please go back and get this resolved correctly ? Thank you. Although the temporary work around is to set the index before browsing the file, often we want to go to the last records added and natural order ( no index ) is the fastest way.

Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 244
Joined: Mon Jun 05, 2006 09:39 PM
Re: xbrowse / ADS failure
Posted: Tue Oct 27, 2015 04:46 PM
All these navigation problems xbrowse already decided to put runs on TADs class, The Linear Sr could study and add in xBrowse class.

In xbrowse.prg method SetRdd() change:
Code (fw): Select all Collapse
   If ( "ADS"$( ::cAlias )->( RddName() ) .or. 'ADT' $ ( ::cAlias )->( RddName() ) ) //.and. ;
      //( ::cAlias )->( LastRec() ) > 200

      // Modified in FWH 9.06
      // AdsGetRelKeyPos() returns approximate position as % and when multipilied by 100 and rounded off
      // returns incorrect values occassionally on smaller  tables. OrdKeyNo() mapped to AdsKeyNo() gives reliable
      // result in such cases. For large tables OrdKeyNo() is unacceptably slow. Limit of 200 is chosen because
      // 0.5% is 1/200.

      cAdsKeyNo    := "{| n, Self | iif( n == nil, " +;
                         "nCalcRelPos( " + cAlias + "->( ADSGetRelKeyPos() ) * Self:nLen, Self ), "+;
                         cAlias + "->( ADSSetRelKeyPos( n / Self:nLen ) ) ) }"

      cAdsKeyCount := "{|| " + cAlias + "->( ADSKeyCount(,,1) )}" 

      DEFAULT ::bKeyNo    := &cAdsKeyNo ,;
              ::bKeyCount := &cAdsKeyCount


Function nCalcRalPos()
Code (fw): Select all Collapse
FUNCTION nCalcRelPos(f_nVal,f_oXBrw)
  Local nLenRegs := f_oXBrw:nLen, nRowPos := f_oXBrw:nRowSel
  Local nRetorno := 0
  
  nRetorno := Round(f_nVal,3)
  
  If nRetorno == 0
    nRetorno := 1
  EndIf

  If nRetorno < nRowPos
    nRetorno := nRowPos
  EndIf  

  nRetorno := Int(nRetorno)

RETURN nRetorno


When I use the TADS class I use the tCtrlxBrw class ()
here is the class, most only works with TADS ().

Class tCtrlxbrw:
Code (fw): Select all Collapse
#Include "Fivewin.ch"
#Include "xBrowse.ch"

#Define df_BaseMySql    1

Class tCtrlxBrw 

  Data oXBrwCtrl, oDbDs_DataBaseAds
  Data bStrData
  Data oGetDsFilter, nTpCampoFilter, cCampoFilter, lLastRecZero
  Data bChangeBrw
  
  Method New(f_oXBrowse,f_oDbDs_DataBaseAds) Constructor
  Method End()

  Method SetTAds()
  
  Method tCtrlxBrw_Skip(f_nKip)
  
  Method tCtrlxBrw_Seek(f_oBjCol,f_uVar)
  Method tCtrlxBrw_EditFilterRdd()
  Method tCtrlxBrw_EditFilterSql()
  Method tCtrlxBrw_EditChange()
  Method tCtrlxBrw_EditClearChar(f_cTxt, f_nTipo)


Endclass
//-----------------------------------------------------------------------------
Method New(f_oXBrowse,f_oDbDs_DataBaseAds,f_aGetFilter) Class tCtrlxBrw
  Local oSelf

  // f_aGetFilter[1] > oBjeto Get
  // f_aGetFilter[2] > Tipo Filtro 1=SetAof contains / 2=Sql select Contains
  // f_aGetFilter[3] > Nome do campo a pesquisar
   
  ///Override Method Skip In Class Txbrowse With oSelf:tCtrlxBrw_Skip

  ::lLastRecZero := .F.

  ::oDbDs_DataBaseAds     := f_oDbDs_DataBaseAds
  ::oXBrwCtrl             := f_oXBrowse
  
  ::oXBrwCtrl:cAlias      := ::oDbDs_DataBaseAds:cAlias
  
  If !Hb_IsNil(f_aGetFilter)

    ::oGetDsFilter    := f_aGetFilter[1]
    ::nTpCampoFilter  := f_aGetFilter[2]
    ::cCampoFilter    := f_aGetFilter[3]
    
    If f_aGetFilter[2] == 2 // Sql Contains
      ::oGetDsFilter:bChange := {||::tCtrlxBrw_EditFilterSql()}
    
    ElseIf f_aGetFilter[2] == 1 // Rdd set aof

      ::oGetDsFilter:bChange := {||::tCtrlxBrw_EditFilterRdd()}
      
    EndIf

    ::bChangeBrw := ::oXBrwCtrl:bChange
    ::oXBrwCtrl:bChange    := {||::tCtrlxBrw_EditChange()}
    ::oXBrwCtrl:bGotFocus  := {||::tCtrlxBrw_EditChange()}
    
  EndIf  

  ::oXBrwCtrl:bClrSel := {|| { CLR_BLACK, CLR_HGRAY} } // Giovany
  ::SetTAds()
  ::oDbDs_DataBaseAds:Refresh()

Return Self
//-----------------------------------------------------------------------------
Method End() Class tCtrlxBrw

Self := Nil

Return Nil
//-----------------------------------------------------------------------------
Method SetTAds() Class tCtrlxBrw
  Local nTpGetRelPos := 1, cTmpQry := "", nTmp := 0

  ::oDbDs_DataBaseAds:lBufferOnSkip := .T.
  
  If ::oDbDs_DataBaseAds:nOpenType == 3 // Open via Dataset
    cTmpQry := Upper(::oDbDs_DataBaseAds:cQrySql)
    If At("{STATIC}",cTmpQry) == 0 
      nTpGetRelPos := 2
    Else
      nTpGetRelPos := 1 
    EndIf
  Else
    nTpGetRelPos := 1
  EndIf

  If nTpGetRelPos == 2 // Open via Sql Dataset cursor vivo 

    ::oXBrwCtrl:bKeyNo    := {| n, _Self | If( n == nil, ;
                                   nCalcRelPos((::oDbDs_DataBaseAds:GetRelKeyPos() * _Self:nLen) /10,::oXBrwCtrl) , ;
                                   ::oDbDs_DataBaseAds:SetRelKeyPos( Round(n / _Self:nLen,3) ) ) }

  Else // Viao Rdd ou Static Cursor

    ::oXBrwCtrl:bKeyNo    := {| n, _Self | If( n == nil, ;
                                 nCalcRelPos((::oDbDs_DataBaseAds:GetRelKeyPos() * _Self:nLen),::oXBrwCtrl ) , ;
                                 ::oDbDs_DataBaseAds:SetRelKeyPos( Round(n / _Self:nLen,3) ) ) }

  EndIf

  ::oXBrwCtrl:bBookMark := {| n | iif( n == nil,;
                               ::oDbDs_DataBaseAds:Recno() , ;
                               ::oDbDs_DataBaseAds:GoTo( n ) ) }

  ::oXBrwCtrl:bKeyCount := {|| ::oDbDs_DataBaseAds:KeyCount(1)  }
  
  ::oXBrwCtrl:bBof      := { ||  ::oDbDs_DataBaseAds:Bof() }
  ::oXBrwCtrl:bEof      := { ||  ::oDbDs_DataBaseAds:Eof() }
  ::oXBrwCtrl:bSkip     := { |n| Iif( n == Nil, n := 1, ), ::tCtrlxBrw_Skip( n )} 
  ::oXBrwCtrl:bGoTop    := { ||  ::oDbDs_DataBaseAds:GoTop() }
  ::oXBrwCtrl:bGoBottom := { ||  ::oDbDs_DataBaseAds:GoBottom() }

  ::oDbDs_DataBaseAds:OnSkip()

Return Nil
//-----------------------------------------------------------------------------
Method tCtrlxBrw_Skip(f_nSkip) Class tCtrlxBrw
  Local nSkipper := 0
  
  Default f_nSkip := 1 

  nSkipper := (::oDbDs_DataBaseAds:cAlias)->(DbSkipper(f_nSkip))

  ::oDbDs_DataBaseAds:OnSkip()
  
Return nSkipper  
//-----------------------------------------------------------------------------
Method tCtrlxBrw_Seek(f_oBjCol,f_uVar,f_lTpSeek) Class tCtrlxBrw
LOCAL nRecMarca := ::oDbDs_DataBaseAds:Recno(), cTpData := ""

  cTpData := VALTYPE(f_uVar)
  
  IF cTpData == "N"
     f_lTpSeek := .F.
  ELSEIF cTpData == "D"
     f_lTpSeek := .F.
  ELSEIF cTpData == "C"
     f_lTpSeek := .T.
  ENDIF
  
  //If ::oDbDs_DataBaseAds:nOpenType == 1
    f_oBjCol:SetOrder()
    ::oDbDs_DataBaseAds:Seek(f_uVar,f_oBjCol:cSortOrder,f_lTpSeek)
  //EndIf
  
  IF ::oDbDs_DataBaseAds:EOF()
  
     ::oDbDs_DataBaseAds:GoTo(nRecMarca)
     
     MSGSTOP("A ocorrencia solicitada não foi encontrada.",;
             "Procedimento abortado...")
  
  ENDIF
  ::oXBrwCtrl:Refresh(.T.)
  
  IF ::oXBrwCtrl:bChange != nil
     EVAL(::oXBrwCtrl:bChange)
  ENDIF

RETURN NIL
//-----------------------------------------------------------------------------
Method tCtrlxBrw_EditFilterRdd() Class tCtrlxBrw
  Local cTxtDigitacao := "", cAof := ""

  //::oGetDsFilter:Save()
  cTxtDigitacao := Alltrim(::tCtrlxBrw_EditClearChar(::oGetDsFilter:cText))

  If Len(cTxtDigitacao) < 5
    cTxtDigitacao := ""
  Else
    ::lLastRecZero := .F.
  EndIf
  
  If ::lLastRecZero
    Return Nil
  EndIf
  ///? cTxtDigitacao

  cAof := "CONTAINS("+::cCampoFilter+","+cTxtDigitacao+")"

    ::oGetDsFilter:oWnd:cTitle := cAof
    ::oGetDsFilter:oWnd:Refresh()
    ///msginfo(cAof)
    
    ::oDbDs_DataBaseAds:Filter(cAof)
    ::oDbDs_DataBaseAds:GoTop()
  ::oXBrwCtrl:Refresh(.T.)

  If Len(cTxtDigitacao) < 5
    ::lLastRecZero := .T.
  EndIf

Return Nil
//-----------------------------------------------------------------------------
Method tCtrlxBrw_EditFilterSql() Class tCtrlxBrw
  Local cTxtDigitacao := ""

  //::oGetDsFilter:Save()
  cTxtDigitacao := Alltrim(::tCtrlxBrw_EditClearChar(::oGetDsFilter:cText))

  If Len(cTxtDigitacao) < 5
    cTxtDigitacao := ""
  Else
    ::lLastRecZero := .F.
  EndIf
  
  If ::lLastRecZero
    Return Nil
  EndIf
  ///? cTxtDigitacao

  ::oDbDs_DataBaseAds:aVarsSql := {{"_TxtDigitacao_",cTxtDigitacao},;
                                   {"_Campo_",::cCampoFilter}}
  
  ::oDbDs_DataBaseAds:DsExecute()
  ::oXBrwCtrl:Refresh(.T.)

  If Len(cTxtDigitacao) < 5
    ::lLastRecZero := .T.
  EndIf

Return Nil
//-----------------------------------------------------------------------------
Method tCtrlxBrw_EditChange() Class tCtrlxBrw

  If ::oDbDs_DataBaseAds:LastRec() == 0
    Return Nil
  EndIf
  
  ::oGetDsFilter:VarPut(::oDbDs_DataBaseAds:VarGet(::cCampoFilter))
  ::oGetDsFilter:Refresh()
  
  If !Hb_IsNil(::bChangeBrw)
    Eval(::bChangeBrw)
  EndIf
  
Return Nil

//-----------------------------------------------------------------------------
Method tCtrlxBrw_EditClearChar(f_cTxt) Class tCtrlxBrw
  Local cRetTxt := f_cTxt
  Local iFor := 0, cAnd := ""
  Local aCharDeletes := { chr(34),"-",".","+","=","&","'","´"}
  Local aPalavras := {}
  
  cRetTxt := _CHAR_CLEAN(cRetTxt,{ " AND ",;
                                      " NEAR ",;
                                      " ANY "})

  For iFor := 1 To Len(aCharDeletes)
    cRetTxt := StrTran(cRetTxt,aCharDeletes[iFor]," ")
  Next

  aPalavras := Hb_aTokens(cRetTxt)

  cRetTxt := ""
  For iFor := 1 To Len(aPalavras)
    If Len(aPalavras[iFor]) > 3
      cRetTxt += (cAnd + Chr(34)+aPalavras[iFor])+Chr(34) //+ " "
      cAnd := " and "
    Endif
  Next

Return cRetTxt
///////////////////////////////////////////////////////////////////////////////
FUNCTION nCalcRelPos(f_nVal,f_oXBrw)
  Local nLenRegs := f_oXBrw:nLen, nRowPos := f_oXBrw:nRowSel
  Local nRetorno := 0
  
  nRetorno := Round(f_nVal,3)
  
  If nRetorno == 0
    nRetorno := 1
  EndIf

  If nRetorno < nRowPos
    nRetorno := nRowPos
  EndIf  

  nRetorno := Int(nRetorno)

RETURN nRetorno
///////////////////////////////////////////////////////////////////////////////
FUNCTION _CHAR_CLEAN(f_cTxt,f_aCaracteresRetira)
    Local cTxtRetorno := f_cTxt, iFor := 0
    
    For iFor := 1 To Len(f_aCaracteresRetira)
    cTxtRetorno := StrTran(cTxtRetorno,f_aCaracteresRetira[iFor],"")
  Next
   
RETURN cTxtRetorno


Exemplo com tAds

Code (fw): Select all Collapse
  ::oDb_BoletoNucleo  := DB_BOLNUCL():OpenRdd()

  ::oBrw361_Remessas                     := tXBrowse():New( ::oDlgBoletosGeral )
  ::oBrw361_Remessas:cAlias              := ::oDb_BoletoNucleo:cAlias
  ::oBrw361_Remessas:nMarqueeStyle       := MARQSTYLE_HIGHLROW
  ::oBrw361_Remessas:nRowDividerStyle    := LINESTYLE_BLACK
  ::oBrw361_Remessas:nColDividerStyle    := LINESTYLE_BLACK
  ::oBrw361_Remessas:nColSel             := 1
  ::oBrw361_Remessas:l2007               := .T.
  ::oBrw361_Remessas:nRowHeight          := 24
  ::oBrw361_Remessas:nHeaderHeight       := 24 
  ::oBrw361_Remessas:bClrRowFocus        := {||{ GetSysColor( 9 ), GetSysColor( 16 )}}
  ::oBrw361_Remessas:lFooter             := .F.

  aadd(aColunas,Nil)
  nColTmp := Len(aColunas)
  aColunas[nColTmp] := ::oBrw361_Remessas:AddCol()
    With Object aColunas[nColTmp]
      :bStrData         := {||::oDb_BoletoNucleo:dProcesso}
      :cHeader          := "Dt. Imp. "
      :nWidth           := 90
      :nDataStrAlign    := AL_RIGHT
      :nHeadStrAlign    := AL_RIGHT
      :cSortOrder       := "dProcesso"
      :nEditType        := EDIT_GET
      //:cEditPicture     := "!"
      //:bEditValue       := {||}
      //:bEditWhen        := {||}
      //:bEditValid       := {||}
      //:aEditListTxt     := {}
      :AddResource("B16_BRWSEEK") // Bitmaps
      :AddResource("B16_LED_RED_1") // Bitmaps
      :nHeadBmpNo       := 1 
      //:bBmpData         := {||}
      //:nBtnBmp          := 2
      //:bEditBlock       := {|oSelf|::Fun_Menus(01,oSelf)}
      :bOnPostEdit      := {|ooBj,vVar,nKey|::oCtrl361_Remessas:tCtrlxBrw_Seek(ooBj,vVar)} // Automatic seek on Presskey
      //:cFooter          := "Total"
      //:bFooter          := {||20+20}
      //:nFootStrAlign    := 1
    //:nTotal           := 0
    //:lTotal           := .T.
      //:nFootStrAlign    := 1 
  
    End With 

  aadd(aColunas,Nil)
  nColTmp := Len(aColunas)
  aColunas[nColTmp] := ::oBrw361_Remessas:AddCol()
    With Object aColunas[nColTmp]
      :bStrData         := {||::oDb_BoletoNucleo:nOcorrencias}
      :cHeader          := "Qta "
      :nWidth           := 30
      :nDataStrAlign    := AL_RIGHT
      :nHeadStrAlign    := AL_RIGHT
  
    End With 


  ::oBrw361_Remessas:SetRDD()
  ::oBrw361_Remessas:CreateFromResource(361)
    
  aColunas[1]:SetOrder()
  ::oBrw361_Remessas:GoTop()
  ::oBrw361_Remessas:SetFocus()
  ::oBrw361_Remessas:Refresh()

  ::oCtrl361_Remessas  := tCtrlxBrw():New(::oBrw361_Remessas,::oDb_BoletoNucleo) // Class tCtrlxBrw control xbrowse
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Re: xbrowse / ADS failure
Posted: Wed Oct 28, 2015 03:57 PM

I appreciate the alternative, but I really think the most appropriate solution is to get a fix for the bug !

Antonio ? Did you receive a response to your inquiries ?

The problem does not exist with xHarbour ( .com ) builds, or DBFCDX, only ADS with Harbour ... so surely we can get the error fixed.

Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: xbrowse / ADS failure
Posted: Wed Oct 28, 2015 10:19 PM

Tim,

Could you prepare a small and self contained example without using FWH that reproduces the error ?

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Re: xbrowse / ADS failure
Posted: Wed Oct 28, 2015 10:28 PM
Antonio,

This has been discussed in another thread, and Rao identified the exact lines in the xBrowse code that creates the error.

In addition, others had the exact same result.

He indicated he knew what was causing the error, but then the topic was never resolved.

Thanks for testing. From the result of your tests we understand that OrdKeyGoTo() works with dbfcdx RDD even when there is no index and with ADS RDD it fails. When I made this change in 2009 I am sure it was working and at that time most of my applications were using ADSCDX.

If you are using Harbour we need to check with xHarbour version also.
Surprisingly it appears these functions are working:
AdsGetRelKeyPos
AdsSetRelKeyPos
AdsGetKeyCount
Theoretically, these functions also should depend on the index still they work.

Interestingly there is AdsGetKeyPos() function in ACE but no comparable function to OrdKeyGoTo()

I suggest you please continue with the change we proposed earlier.
I study both xHarbour and Harbour versions of the RDD source and also Advantage documentation and implement a dependable solution.


That dependable solution was never provided.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: xbrowse / ADS failure
Posted: Wed Oct 28, 2015 10:34 PM

We need Rao help on this

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 3022
Joined: Fri Oct 07, 2005 01:45 PM
Re: xbrowse / ADS failure
Posted: Mon Nov 02, 2015 03:47 PM

Did you get in touch with him ?

Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: xbrowse / ADS failure
Posted: Mon Nov 02, 2015 04:19 PM

Mr Tim

I'll get back on this very soon

Regards



G. N. Rao.

Hyderabad, India
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: xbrowse / ADS failure
Posted: Sun Dec 06, 2015 10:43 AM

Resolved in FWH 15.10
Please see

viewtopic.php?f=3t=31485p=184767#p184767

&&

Regards



G. N. Rao.

Hyderabad, India

Continue the discussion