macro substitution & in fieldnames

macro substitution & in fieldnames

Postby Marc Venken » Tue Oct 25, 2016 9:16 pm

It is a piece of code for a mapping system

I have 3 databases

dbf1 -> with just 1 record filled with fieldnames of dbf 2
ID : "STYLE"
NAME : "TITLE"
CATMAIN : "CAT1"
...

dbf2 -> actual datafile (source data)
STYLE : "200444"
TITLE : "Safetyshoes dassy"
CAT1 : "Safetyshoes"
....

dbf3 -> target datafile where i what to put the data from dbf2
ID : "CUST->STYLE" -> should be "200444"
NAME : "CUST->TITLE" -> should be 'Safetyshoes dassy"
CATMAIN : "CUST->CAT1" ->should be 'Safetyshoes"

So, I do something wrong with the & operator

Here I miss the logic of converting strings
Code: Select all  Expand view

             if apos > 0  // if >0, it is a fieldname else a standard data like "21%"
                cTarget = "slave->"+fieldname(i)

  //            cField = "CUST->"+aCustfields[i]
                cField = "CUST->"+cLookup

 //               cData = &cField // not working
                cData = cField

              &cTarget = cData
            else  // standard data, but no fieldname
                cData = cField  
                &cTarget = cData
           endif

 



Full Function

Code: Select all  Expand view

function filldbf()
   Local aCustfields:={}

   use slave
   select slave
   zap
   close
   use DASSY NEW alias CUST
   use slave NEW alias slave
   use master NEW alias master

   select cust
   for i = 1 to cust->(FCOUNT())
      AADD(aCustfields,Fieldname(i))  // make arry with all fieldnames from datafile
   next

   select master
   master->(dbgotop())
   nMasterfields = master->(fcount())
   cust->(dbgotop())
   nTel = 0

   do while !cust->(eof())
      slave->(dbappend())

      for i = 1 to nMasterfields

         cWelkField = "master->"+fieldname(i)
         clookup = alltrim(&cWelkfield)        // data from the masterfile, result = fieldname to look for next
         if !empty(clookup)
            apos = ascan(aCustfields,clookup)  // to see if the data is a fieldname, could also be simple data

             if apos > 0  // found as a fieldname
                cTarget = "slave->"+fieldname(i)

  //            cField = "CUST->"+aCustfields[i]
                cField = "CUST->"+cLookup

 //               cData = &cField // not working
                cData = cField

              &cTarget = cData
            else  // standard data, but no fieldname
                cData = cField  // GIVES THE DATA, BUT ERROR FOR THE NEXT DO/ENDDO LOOK
                &cTarget = cData
           endif
         endif
        next
      cust->(dbskip())
   enddo

   select slave
   xbrowse()
   close all
return
 


The result is a database filled with the fieldnames, but not the fielddata

Image
Marc Venken
Using: FWH 23.04 with Harbour
User avatar
Marc Venken
 
Posts: 1371
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: macro substitution & in fieldnames

Postby cnavarro » Wed Oct 26, 2016 12:13 am

Look, I hope it's what you need

Code: Select all  Expand view


#include "Fivewin.ch"

MEMVAR cAlias

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

Function Main()

   //local cAlias
   local cField
   local uVal
   
Use "Customer.dbf" ALIAS custom
   
   cAlias := Alias()
   
   cField := ( cAlias )->( FieldName( 1 ) )
   ? ( cAlias )->( FieldName( 1 ) ), ( cAlias )->( FieldGet( 1 ) )
   uVal := ( cAlias )->First
   ? uVal, cField
   cField := "( cAlias )->"+cField
   ? &(cField)
   &(cField)  := "Field modified"
   //   &(cField)  := "Homer"
   ? ( cAlias )->( FieldGet( 1 ) )

Return nil

 
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6504
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: macro substitution & in fieldnames

Postby dutch » Wed Oct 26, 2016 7:57 am

Dear Marc,

I use as you did but a bit different.
Code: Select all  Expand view

RvName := 'MHS->MHS_RV'+right(dtos(MEMVAR->comdat),2)
&(RvName) += round(TRN->TRN_UNIT * TRN->TRN_QTTY,2)
 
Regards,
Dutch

FWH 19.01 / xHarbour Simplex 1.2.3 / BCC73 / Pelles C / UEStudio
FWPPC 10.02 / Harbour for PPC (FTDN)
ADS V.9 / MySql / MariaDB
R&R 12 Infinity / Crystal Report XI R2
(Thailand)
User avatar
dutch
 
Posts: 1535
Joined: Fri Oct 07, 2005 5:56 pm
Location: Thailand

Re: macro substitution & in fieldnames

Postby hmpaquito » Wed Oct 26, 2016 8:42 am

Macro substitution is bad:
- slow (more slow than dbf field functions)
- avoid compiler syntax analisys.


Better harbour programming style is do not use macro substitution, so:

Code: Select all  Expand view
// With preprocessor  is more rapid and clear with pseudo functions:
#Define FPOS_(aTarget) ;
            (aTarget[1])-> ( FieldPos(aTarget[2]) )
#Define FPUT(aTarget, xValue) ;
            (aTarget[1])-> ( FieldPut( FPOS_(aTarget), xValue) )
#Define FGET_(aTarget) ;
            (aTarget[1])-> ( FieldGet( FPOS_(aTarget), xValue) )

// Sample:
aTarget:= {"slave", fieldname(1)}

FPUT_(aTarget, "hi !")
xVar:= FGET_(aTarget)
nPos:= FPOS_(aTarget)


Regards
hmpaquito
 
Posts: 1482
Joined: Thu Oct 30, 2008 2:37 pm

Re: macro substitution & in fieldnames

Postby puenteda » Wed Oct 26, 2016 3:19 pm

Marc:

Look at this examples code:

PADRON->(DBGOTOP())
DO WHILE !PADRON->(EOF())

IF !TMOVMES->(DBSEEK(CONCEPTO->COD+PADRON->MP,.F.))

TPADRON->(DBAPPEND())
COPIAREG('TPADRON','PADRON')

ENDIF

PADRON->(DBSKIP())
ENDDO

FUNCTION COPIAREG(xBaseEntra,xBaseSale)

Local aCampos:={},i,aDatos:={},aCampos2,aAt

aCampos:=(xBaseEntra)->(dbstruct())
aCampos2:=(xBaseSale)->(dbstruct())

FOR I:=1 TO LEN(aCampos2)
IF ASCAN(aCampos,{|aAt| aAt[1]==aCampos2[i,1]}) >0
(xBaseEntra)->&(aCampos2[i,1]):=( xBaseSale )->&(aCampos2[i,1])
ELSE
* ? 'NO EXISTE EL CAMPO EN ',XBASEENTRA,'I=',I,aCampos2[i,1]
ENDIF
NEXT

return nil


BUS_DES('PADRON',2,MOVMES->MP,'ESPE')

Function BUS_DES(XARCH, XORDEN, XCLAVE, XCAMPO)

Local RET:=SPAC(0) , ORD_ACT, AREA_ACT := SELECT(), cRegis

IF SELECT(XARCH) == 0
USE (WPATH + "\" + XARCH) SHARED NEW
ENDIF

DBSELECTAR(XARCH)
cRegis:=RECNO()
ORD_ACT = INDEXORD()

SET ORDER TO XORDEN

DBSEEK((XCLAVE))
IF FOUND() .AND. !DELETED()
RET = EVAL(FIELDBLOCK(XCAMPO))
ELSE
DBGOBOTTOM()
RET = SPACE(LEN(EVAL(FIELDBLOCK(XCAMPO))))
ENDIF
SET ORDER TO ORD_ACT
DBGOTO(cRegis)
SELECT(AREA_ACT)

RETURN RET


Regards,
Daniel Puente
puenteda
 
Posts: 24
Joined: Thu Oct 02, 2014 3:51 am

Re: macro substitution & in fieldnames

Postby Marc Venken » Wed Oct 26, 2016 11:37 pm

Thanks guys,

With the samples I get it to work !

hmpaquito wrote:Macro substitution is bad:
- slow (more slow than dbf field functions)
- avoid compiler syntax analisys.

Better harbour programming style is do not use macro substitution:


Out of curiosity, You suggested code from Harbour Style.
I'm just new with the FW programming and my skilss are not ready for it yet,
but I wonder how your working code would look like. Here is the code that works for me now.
Should you have any time, i would be a great learning stuff for me.

Code: Select all  Expand view


function filldbf()
   Local aCustfields:={}
   local cField
   local uVal
   local cM_field

   MEMVAR cAlias

   use slave
   select slave
   zap
   close
   use DASSY NEW alias CUST
   use slave NEW alias slave
   use master NEW alias master

   select cust
   AliasCust = alias()
   select slave
   Aliasslave = alias()
   select master
   Aliasmaster = alias()

   select cust
   for i = 1 to cust->(FCOUNT())
      AADD(aCustfields,Fieldname(i))  // make arry with all fieldnames from datafile
   next

   select master
   master->(dbgotop())
   nMasterfields = master->(fcount())

   master->(dbgotop())
   cust->(dbgotop())
   do while !cust->(eof())
      slave->(dbappend())
      for i = 1 to nMasterfields
         cM_Field := alltrim(( Aliasmaster )->(FieldGet(i)))
         if !empty(cM_Field)
             nPos = ascan(aCustfields,cM_Field)  // to see if the data is a fieldname, could also be simple data
             cSlaveField := "slave->"+(aliasslave)->(fieldname(i))
             if nPos > 0  // found as a fieldname
                &(cSlavefield) := cust->(fieldget(nPos))
             else  // standard data, but no fieldname
                &(cSlavefield) := &(AliasMaster)->(fieldget(I))
             endif
         endif
        next
      cust->(dbskip())
   enddo
   select slave
   xbrowse()
   close all
return


 
Marc Venken
Using: FWH 23.04 with Harbour
User avatar
Marc Venken
 
Posts: 1371
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium

Re: macro substitution & in fieldnames

Postby hmpaquito » Thu Oct 27, 2016 7:24 am

Here you are:

Code: Select all  Expand view


function filldbf()
   Local aCustfields:={}
   local cField
   local uVal
   local cM_field

   // MEMVAR cAlias

   use slave
   select slave
   zap
   close
   use DASSY NEW alias CUST
   use slave NEW alias slave
   use master NEW alias master

   select cust
   AliasCust = alias()
   select slave
   Aliasslave = alias()
   select master
   Aliasmaster = alias()

   select cust
   for i = 1 to cust->(FCOUNT())
      AADD(aCustfields,Fieldname(i))  // make arry with all fieldnames from datafile
   next

   select master
   master->(dbgotop())
   nMasterfields = master->(fcount())

   master->(dbgotop())
   cust->(dbgotop())
   do while !cust->(eof())
      slave->(dbappend())
      for i = 1 to nMasterfields
         cM_Field := alltrim(( Aliasmaster )->(FieldGet(i)))
         if !empty(cM_Field)
             nPos = ascan(aCustfields,cM_Field)  // to see if the data is a fieldname, could also be simple data
             cSlaveField := "slave->"+(aliasslave)->(fieldname(i))
             if nPos > 0  // found as a fieldname
                // &(cSlavefield) := cust->(fieldget(nPos))
                Slave-> ( FieldPut ( i,  Cust->(FieldGet(nPos)) )  // This and...
             else  // standard data, but no fieldname
                // &(cSlavefield) := &(AliasMaster)->(fieldget(I))
                Slave-> ( FieldPut ( i,  (cAliasMaster)->(FieldGet(i)) )  // ... this
             endif
         endif
        next
      cust->(dbskip())
   enddo
   select slave
   xbrowse()
   close all
return


 
hmpaquito
 
Posts: 1482
Joined: Thu Oct 30, 2008 2:37 pm

Re: macro substitution & in fieldnames

Postby Marc Venken » Thu Oct 27, 2016 10:26 pm

Thanks,

It works! and is better for reading the code.

Learning every day..

Thanks.
Marc Venken
Using: FWH 23.04 with Harbour
User avatar
Marc Venken
 
Posts: 1371
Joined: Tue Jun 14, 2016 7:51 am
Location: Belgium


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 72 guests