FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Problem with FW_ArrayToDBF(New) RESOLVED!!!
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Problem with FW_ArrayToDBF(New) RESOLVED!!!
Posted: Sat Jan 12, 2019 09:29 AM
I have a Dbf as products
When The final User insert a product into a Invoice it wish show all products to select one from a lookup dialog.



at the init you can see this, the last column is the order position from 1 to 7


The Final User wish also show some products first and I thinked to order the poducts add a Numeric filed "ORDINE" where insert a number from 1 to n
The final user can sect one product and Move on UP or on Down to order the product position.



to simulate inserting a record, please press the button "Simulation insert record"
when I insert a record at init the field->Order is 0, the user must make the position order



to simulate the order of position, please press "Simulation order"



To do this I thought of creating a simple dialog and finally save the result in the dbf but
I have difficulty because the new function FW_ArrayToDBF does not run well and when you rewrite the records you lose some records





I made this test complete of creation of dbf for understand the problem I also not resolved


Code (fw): Select all Collapse
#include "Fivewin.ch"
#include "constant.ch"

REQUEST HB_Lang_IT
REQUEST HB_CODEPAGE_ITWIN

REQUEST DBFCDX
REQUEST DBFFPT
EXTERNAL ORDKEYNO,ORDKEYCOUNT,ORDCREATE,ORDKEYGOTO

//TEST for Order

 FUNCTION Main()

      HB_LangSelect("IT")
      HB_SetCodePage("ITWIN")

   SET _3DLOOK ON
   SET CENTURY ON
   SET DATE ITALIAN

   RDDSetDefault( 'DBFCDX' )

   TEST()

RETURN NIL

//--------------------------------------------------//

Function Test()
Local oDlg,oBrw,oFont
Local oBtnInsert,oBtnOrd

Create_Testfile()  //create test.dbf

USE TEST ALIAS TEST SHARE NEW
test->(dbsetorder(1))



   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-14


   DEFINE DIALOG oDlg SIZE 878,570 ;
   PIXEL TRUEPIXEL RESIZABLE FONT oFont ;
   TITLE "Test"



 @ 55, 40 XBROWSE oBrw SIZE -20,-65 PIXEL OF oDlg;
           COLUMNS 5,2,4,7,8,9,12,11;
           HEADERS "Tipo","Descrizione","Costo","Disp.","A4", "Pos", "Ord.","";
           COLSIZES 40,310,50,50,28,28,30,34 ;
           CELL LINES NOBORDER ;
           DATASOURCE "TEST"


              WITH OBJECT oBrw
                  :CreateFromCode()
                 END


  @ 520,10 BUTTON oBtnInsert ;
             PROMPT "Simulation Insert Record"  SIZE 200,45 PIXEL OF oDlg;
                 ACTION Sumulation_insert_record(oBrw)



 @ 520,660 BUTTON oBtnOrd ;
             PROMPT "Simulation Order"  SIZE 200,45 PIXEL OF oDlg;
                 ACTION Order(oBrw)

   oDlg:bResized  := <||
      local oRect    := oDlg:GetCliRect()
      local x        := Int( oRect:nWidth / 2 )
      oBtnInsert:nLeft   := oRect:nLeft+20
      oBtnInsert:nTop    := oRect:nBottom - 50

      oBtnOrd:nLeft      := oRect:nRight - 220
      oBtnOrd:nTop       := oRect:nBottom - 50
       return nil
       >

 ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont

   return nil




//------------------------------------------------------------------//
Function Order(oGrid)
Local oDlgOrd,oLbx,oFont
Local aArray
local cFieldList:="id,name,breve,price,image,struttura,unit,a4,pos,multiple,islock,ordine"
local nLen

   Local  nBottom   := 29
   Local  nRight    := 60
   Local  nWidth :=  Max( nRight * DLG_CHARPIX_W, 180 )
   Local  nHeight := nBottom * DLG_CHARPIX_H


     TEST->( DbSetOrder( 2 ) )
     aArray:= TEST->( FW_DbfToArray(cFieldList) )
     nLen   := Len( aArray )
     xbrowser aArray

  DEFINE FONT oFont NAME "VERDANA" SIZE 0,-14
  DEFINE DIALOG oDlgOrd   SIZE 600, 480

     @ 5, 2 XBROWSE  oLbx OF oDlgOrd ;
            DATASOURCE  aArray  ;
            COLUMNS 5,2 ;
            HEADERS "Servizio","Desc" ;
            SIZE 200,210 PIXEL FONT oFont

             WITH OBJECT  oLbx
                     WITH OBJECT  oLbx:aCols[1]
                               :cDataType     := 'F'
                               :nWidth        := 80
                               :nDataBmpAlign := AL_CENTER
                               :lBmpTransparent := .T.
                            END

            :lheader:=.f.
                      :nMarqueeStyle       := MARQSTYLE_HIGHLWIN7
                      :lHscroll         := .F.
                      :l2007            := .F.
                      :l2015            := .T.
                      :nStretchCol  := STRETCHCOL_WIDEST
                      :lAllowRowSizing     := .F.
                      :lAllowColSwapping   := .F.
                      :lAllowColHiding     := .F.
                      :lRecordSelector     := .F.
                      :CreateFromCode()
                   END



   @ 22,208 BUTTON oBtnUp    PROMPT "&UP" ;
               SIZE 80,25 PIXEL OF  oDlgOrd  ;
               ACTION  IIF( oLbx:nArrayAt > 1,;
                ( SwapUpArray( oLbx:aArrayData, oLbx:nArrayAt ) ,;
                  oLbx:nArrayAt --                      ,;
                  oLbx:Refresh()                   ),;
                MsgStop("Non si può cambiare la colonna." ))


    @ 72,208 BUTTON oBtnDown PROMPT "&Down" ;
               SIZE 80,25 PIXEL OF  oDlgOrd;
              ACTION  IIF( oLbx:nArrayAt < nLen,;
                ( SwapDwArray( oLbx:aArrayData, oLbx:nArrayAt ) ,;
                  oLbx:nArrayAt ++                      ,;
                  oLbx:Refresh()                   ),;
                MsgStop("Non si può cambiare la colonna." ))


     @ 122,208 BUTTON oBtnOrdine    PROMPT "&Save" ;
               SIZE 80,25 PIXEL OF  oDlgOrd ;
               ACTION oDlgOrd:end( IDOK )


    @ 162,208 BUTTON oBtnUscita    PROMPT "&Exit" ;
               SIZE 80,25 PIXEL OF  oDlgOrd  ;
               ACTION oDlgOrd:end( IDCANCEL )



       ACTIVATE DIALOG oDlgOrd CENTER
            if oDlgOrd:nresult == IDOK

                // SAVE THE new POSITION
                  For n= 1 to Len(aArray)
                       aArray[n][12]:=n
                    next


          SELECT test
      *    dbzap

     *test->( FW_ArrayToDBF( aArray, "id,name,breve,price,image,struttura,unit,a4,pos,multiple,islock,ordine" ) )
      *                     test->( DBGOTOP() )


test->( DBGOTOP() )
test->( FW_ArrayToDBF( aArray, cFieldList, nil, .T. ) ) // Overwrite existing data


Endif

 if oGrid != nil
      oGrid:Refresh()
      oGrid:SetFocus( .t. )
   endif

  return nil

  function SwapDwArray( aArray, nPos )

   local uTmp

   DEFAULT nPos   := len( aArray )

   if nPos < len( aArray ) .and. nPos > 0
      uTmp              := aArray[nPos]
      aArray[nPos]      := aArray[nPos + 1 ]
      aArray[nPos + 1 ] := uTmp
   end if

return nil
//----------------------------------------------------------//

function SwapUpArray( aArray, nPos )

   local uTmp

   DEFAULT nPos   := len( aArray )

   if nPos <= len( aArray ) .and. nPos > 1
      uTmp              := aArray[nPos]
      aArray[nPos]      := aArray[nPos - 1 ]
      aArray[nPos - 1 ] := uTmp
   end if

   return nil














//--------------------------------------------------------------//
function Create_Testfile()
local aFields   := { { "id"    , "C",    4, 0 },;
                     { "name"  , "C",   30, 0 },;
                     { "breve"  , "C",  10, 0 },;
                     { "price" , "N",    9, 2 },;
                     { "image" , "C",   30, 0 },;
                     { "struttura","C", 30, 0 },;
                     { "unit"  , "N",    4, 0 },;
                     { "a4"    , "L",    1, 0 },;
                     { "pos"   , "L",    1, 0 },;
                     { "multiple", "L",  1, 0 },;
                     { "islock"  , "L",  1, 0 },;
                     { "ordine"  , "N",  2, 0 } }


REQUEST DBFCDX

DbCreate( "test.dbf", aFields, "DBFCDX" )

USE test.dbf NEW VIA "DBFCDX"

If test->(eof())

appe blank
field->ID:="0001"
field->name:="Service1"
field->Breve:="Ser1"
field->price:=10.00
field->image:="\images\1.jpg"
field->struttura:=""
field->unit:=0
field->a4:=.t.
field->pos:=.f.
field->multiple:=.f.
field->islock:=.t.
field->ordine:=1

appe blank
field->ID:="0002"
field->name:="Service2"
field->Breve:="Ser2"
field->price:=10.00
field->image:="\images\2.jpg"
field->struttura:=""
field->unit:=0
field->a4:=.t.
field->pos:=.f.
field->multiple:=.f.
field->islock:=.t.
field->ordine:=2

appe blank
field->ID:="0003"
field->name:="Service3"
field->Breve:="Ser3"
field->price:=10.00
field->image:="\images\3.jpg"
field->struttura:=""
field->unit:=0
field->a4:=.t.
field->pos:=.f.
field->multiple:=.f.
field->islock:=.t.
field->ordine:=3

appe blank
field->ID:="0004"
field->name:="Service4"
field->Breve:="Ser4"
field->price:=10.00
field->image:="\images\4.jpg"
field->struttura:=""
field->unit:=0
field->a4:=.t.
field->pos:=.f.
field->multiple:=.f.
field->islock:=.t.
field->ordine:=4

appe blank
field->ID:="0005"
field->name:="Service5"
field->Breve:="Ser5"
field->price:=10.00
field->image:="\images\5.jpg"
field->struttura:="[BED][BED]"
field->unit:=0
field->a4:=.t.
field->pos:=.f.
field->multiple:=.t.
field->islock:=.t.
field->ordine:=5

appe blank
field->ID:="0006"
field->name:="Service6"
field->Breve:="Ser6"
field->price:=10.00
field->image:="\images\6.jpg"
field->struttura:="[BED][CHAIR]"
field->unit:=0
field->a4:=.t.
field->pos:=.f.
field->multiple:=.t.
field->islock:=.t.
field->ordine:=6

appe blank
field->ID:="0007"
field->name:="Service7"
field->Breve:="Ser7"
field->price:=10.00
field->image:="\images\7.jpg"
field->struttura:="[CHAIR][CHAIR]"
field->unit:=0
field->a4:=.t.
field->pos:=.f.
field->multiple:=.t.
field->islock:=.t.
field->ordine:=7

endif

close data


USE TEST ALIAS TEST
INDEX ON TEST->ID TAG ID TO TEST FOR !deleted()
INDEX ON TEST->NAME TAG NAME TO TEST FOR !deleted()
INDEX ON TEST->ORDINE TAG ORDINE TO TEST FOR !deleted()



return nil
//---------------------------------------------------------------//

Function Sumulation_insert_record(oGrid)
   Local nNumber := 0

    EDITVARS nNumber

appe blank
field->ID:=strzero(nNumber,4)
field->name:="Service"+alltrim(str(nNumber))
field->breve:="Ser"+alltrim(str(nNumber))
field->price:=10.00
field->image:="\images\"+alltrim(str(nNumber))+".jpg"
field->struttura:=""
field->unit:=0
field->a4:=.t.
field->pos:=.f.
field->multiple:=.f.
field->islock:=.t.
field->ordine:=0

   if oGrid != nil
      oGrid:Refresh()
      oGrid:SetFocus( .t. )
   endif


return nil
//--------------------------------------------------------------------//




When I press up or down I can move a record up or down then I must save
the procedure of save use this function

Code (fw): Select all Collapse
test->( DBGOTOP() )
test->( FW_ArrayToDBF( aArray, cFieldList, nil, .T. ) ) // Overwrite existing data


and then refresh the xbrowse

On Oldest application I made a dbzap of archive and the FW_ArrayToDBF() function save right all records

Code (fw): Select all Collapse
SELECT test
          dbzap

     *test->( FW_ArrayToDBF( aArray, "id,name,breve,price,image,struttura,unit,a4,pos,multiple,islock,ordine" ) )
      *                     test->( DBGOTOP() )


But Now I must use a dbf with share new and I have this problem
because I cannot use Dbzap



you can see it not run ok sometimes take the first record and make a copy erased other records

sample:

for a sample I move the record number 1 to bottom and the record number 7 to top and then I press save button



then when I return to xbrowse

there are the errors as you can see here



where is the number 1 ?
there are two number 7



I tried also to make the save to hand with ( I must use share new dbf
and replace all record into archive

Code (fw): Select all Collapse
 n:= 1
                        (oServizi)->( DBGOTOP() )
                   Do while .not. (oServizi)->( eof() )
                    IF RecLock(oServizi)
                          (oServizi)->id       := aArray[n][1]
                          (oServizi)->name     := aArray[n][2]
                          (oServizi)->breve    := aArray[n][3]
                          (oServizi)->price    := aArray[n][4]
                          (oServizi)->image    := aArray[n][5]
                          (oServizi)->struttura:= aArray[n][6]
                          (oServizi)->unit     := aArray[n][7]
                          (oServizi)->a4       := aArray[n][8]
                          (oServizi)->pos      := aArray[n][9]
                          (oServizi)->multiple := aArray[n][10]
                          (oServizi)->islock   := aArray[n][11]
                          (oServizi)->ordine   := aArray[n][12]
                          (oServizi)->( dbunlock() )
                           (oServizi)->( Dbcommit() )
                          endif
                          n++
                        (oServizi)->( dbskip() )
                     Enddo
            
                    Endif


but also this not run well



Someone have a solution ?
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Problem with FW_ArrayToDBF(New)
Posted: Sun Jan 13, 2019 04:17 PM
We confirm that the function FW_ArrayToDBF(...) with the new lOverWrite parameter is working perfectly.

This is the test program to demonstrate its functionality.
Code (fw): Select all Collapse
#include "fivewin.ch"

REQUEST DBFCDX

function Main()

   local aData
   local cFieldList  := "FLD1,FLD2,FLD3,FLD4"

   CreateTestDBF()

   USE TEST NEW SHARED VIA "DBFCDX"
   XBROWSER "TEST" TITLE "TEST.DBF : Before Change"

   TEST->( DBGOTOP() )
   aData    := TEST->( FW_DbfToArray( cFieldList ) )

   XBROWSER aData TITLE "Array : Ctrl-Up/Dn for Swap Up/Dn"

   AEval( aData, { |a,i| a[ 4 ] := i } )

   TEST->( DBGOTOP() )
   aData    := TEST->( FW_ArrayToDbf( aData, cFieldList, nil, .T. ) )
   TEST->( DBGOTOP() )

   XBROWSER "TEST" TITLE "TEST.DBF : After Change"

return nil


This is the function for creating the TEST.DBF:
Code (fw): Select all Collapse
static function CreateTestDbf()

   local aCols       := { ;
         { "FLD1",      "N",  5, 0 }, ;
         { "FLD2",      "C", 20, 0 }, ;
         { "FLD3",      "C", 20, 0 }, ;
         { "FLD4",      "N",  5, 0 }  }

   local aData       := { ;
         { 1, "one",       "two",      1 }, ;
         { 2, "three",     "four",     2 }, ;
         { 3, "five",      "six",      3 }, ;
         { 4, "seven",     "eight",    4 }, ;
         { 5, "nine",      "ten",      5 }, ;
         { 6, "eleven",    "twelve",   6 }, ;
         { 7, "thirteen",  "fourteen", 7 }  }

   DBCREATE( "TEST.DBF", aCols, "DBFCDX", .T. )
   FW_ArrayToDBF( aData )
   CLOSE DATA

return nil


Regards



G. N. Rao.

Hyderabad, India
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: Problem with FW_ArrayToDBF(New)
Posted: Sun Jan 13, 2019 11:14 PM
Mr Rao,
First I must use that procedure into a tablet screen where I cannot use Ctrl-Up/Dn for Swap Up/Dn
I have to use the buttons to move the lines, as I can do to simulate the keyboard command Ctrl-Up / Dn for Swap Up / Dn ?

However reviewing my example I did not find the error that continues to manifest
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Problem with FW_ArrayToDBF(New)
Posted: Sun Jan 13, 2019 11:30 PM
where I cannot use Ctrl-Up/Dn for Swap Up/Dn

You can use buttons also. This is a very simple thing.
The point is the function FW_ArrayToDBF() works correctly and it has nothing to do whether you use keyboard or buttons.
Regards



G. N. Rao.

Hyderabad, India
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Problem with FW_ArrayToDBF(New)
Posted: Sun Jan 13, 2019 11:42 PM

You are reading the dbf into array and saving again only for the purpose of swapping rows up and down. This is not necessary. We should be able to swap dbf records up and down directly. That is simpler.

Regards



G. N. Rao.

Hyderabad, India
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: Problem with FW_ArrayToDBF(New)
Posted: Mon Jan 14, 2019 12:15 AM

I found the error on my sample

TEST->( DbSetOrder( 3 ) ) // Index on Ordine field
TEST->( DBGOTOP() )

instead of

  TEST-&gt;( DbSetOrder( 2 ) )   // error  Index on  Name field

Sorry....

Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: Problem with FW_ArrayToDBF(New)
Posted: Mon Jan 14, 2019 12:17 AM
nageswaragunupudi wrote:
where I cannot use Ctrl-Up/Dn for Swap Up/Dn

You can use buttons also. This is a very simple thing.
The point is the function FW_ArrayToDBF() works correctly and it has nothing to do whether you use keyboard or buttons.


wich method of xbrowse I can call to make action with buttons
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Problem with FW_ArrayToDBF(New) RESOLVED!!!
Posted: Mon Jan 14, 2019 01:56 AM

oBrw:SwapUp()
oBrw:SwapDn()

Regards



G. N. Rao.

Hyderabad, India
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: Problem with FW_ArrayToDBF(New) RESOLVED!!!
Posted: Mon Jan 14, 2019 08:17 AM

thanks but here also not run ok
the samples run ok when I insert the code on my application not run, I not understood why
Do you remember I have two xbrowse with servizi.dbf with 2 filter ( single and multiple)
then when I go to order position I use servizi witthout filter and then return to first dialog where are the two xbrowses having the filters

Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com

Continue the discussion