How to SCAN substrings in a dbf - Summer 87

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

How to SCAN substrings in a dbf - Summer 87

Mensagem por alxsts »

Hi!

Added some commets to the code to reply your questions.

Código: Selecionar todos

IF LEN(cString) > 0
   *something was found in the cases Table, save it.
   APPEND BLANK    <-----------------Why do we need to APPEND here?   Add a new blank record to tempTable It's the currently selected area at this moment)
   IF .Not. NetErr()  * if append succeed
     tmpTable->CAS_COMPNY = Cases->CAS_COMPNY   * write company name field. Its the cases table key field in order 7 and will be used later to SEEK the selected company name
     tmpTable->CAS_LNAME = UPPER(cString)       * write the search result
   ELSE
     *Error. Display some message and Exit
     DO DISP_MSG with [Error writing temporary file. Press a key to exit.]
     SELECT CASES
     Go SAV_REC
     RETURN
   ENDIF
  ENDIF
  Cases->(DbSkip())     <--------------What does this statement do?   * skips to nexts record in the cases table

   Also, i know this was the original code our programmer put in here but after researching this I still don't understand what this statement really does:
 
   *-----------------------------------
   *Get client index
   *-----------------------------------
   Set Order to 7   <-------------------   After you have chosen something in the DbEdit() you have closed the tempTable 
                                           and returned to main table (cases). 
                                           This table has several index keys. 
                                           Position in order 7 (probably ordered by company name) in order to SEEK the chosen name. 
 
There is a line I placed that concatenates last and first names. But I don't know what's the first name colum name (see a line where I commented "Assuming there is a column CASE_FNAME"). This line should conatenate both fields, separated by a comma.
[]´s
Alexandre Santos (AlxSts)
marge0512
Usuário Nível 3
Usuário Nível 3
Mensagens: 121
Registrado em: 20 Mai 2011 12:42
Localização: United States

How to SCAN substrings in a dbf - Summer 87

Mensagem por marge0512 »

Thanks for explaining this information! I understand more now. I did use the concatenation of the last and first name that you had written. You actually named the first name field correctly so that was a good guess.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

How to SCAN substrings in a dbf - Summer 87

Mensagem por alxsts »

Hi,
marge0512 escreveu:Now, I'm working on how to match the first names with the last names. All of the last names show but the first do not.
Is it working well now? Are the names showing correctly?
[]´s
Alexandre Santos (AlxSts)
marge0512
Usuário Nível 3
Usuário Nível 3
Mensagens: 121
Registrado em: 20 Mai 2011 12:42
Localização: United States

How to SCAN substrings in a dbf - Summer 87

Mensagem por marge0512 »

The first names are still not showing. I'm debugging now to find out what is going on.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

How to SCAN substrings in a dbf - Summer 87

Mensagem por alxsts »

Hello!

If you want, post the code again.
[]´s
Alexandre Santos (AlxSts)
marge0512
Usuário Nível 3
Usuário Nível 3
Mensagens: 121
Registrado em: 20 Mai 2011 12:42
Localização: United States

How to SCAN substrings in a dbf - Summer 87

Mensagem por marge0512 »

Let me know if you need all the coding posted but I found this when I was debugging:

Código: Selecionar todos

DO WHILE Cases->(!EOF())
                    cString = ""
                   *Search LName first because if REC2FIND exists in both
                   *fields, LNAME takes precedence.
                   *---------------------------------------------------                    
                    IF (REC2FIND $ UPPER(Cases->CASE_LNAME))
                       *Person’s last and first names
                       cString = Trim(Cases->CASE_LNAME+", "+Cases->CASE_FNAME)  [color=#FF0000]<----------Here, cString displays last name and first. No problem.[/color]                    ELSEIF (REC2FIND $ UPPER(Cases->COMPNY_NAM))
                       *Company Name
                       cString = Trim(Cases->COMPNY_NAM)
                    ENDIF                  
                  Altd()
                    IF LEN(cString) > 0
                       *something was found, save it.
                       APPEND BLANK
                       IF .Not. NetErr()
                          tmpTable->COMPNY_NAM = Cases->COMPNY_NAM
                          tmpTable->CASE_LNAME = UPPER(cString)  [color=#FF0040]<------------------Here, tmpTable->CASE_LNAME only displays the last name.[/color] 
                       ELSE
                          *Error. Display some message and Exit
                          DO DISP_MSG with [Error writing temporary file. Press a key to exit.]
                          SELECT CASES
                          Go SAV_REC
                          RETURN
                       ENDIF
                    ENDIF
                    Cases->(DbSkip())
                 ENDDO
Is it possible that tmpTable->CASE_LNAME field display is not large enough? If that makes sense......
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

How to SCAN substrings in a dbf - Summer 87

Mensagem por alxsts »

What's the length of both fields concatenated?
[]´s
Alexandre Santos (AlxSts)
marge0512
Usuário Nível 3
Usuário Nível 3
Mensagens: 121
Registrado em: 20 Mai 2011 12:42
Localização: United States

How to SCAN substrings in a dbf - Summer 87

Mensagem por marge0512 »

I believe together it is a total of 40. They usually allow 25 for the last name and 15 for the first.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

How to SCAN substrings in a dbf - Summer 87

Mensagem por alxsts »

Hello!

Here goes the entire code again. Please, compare with your version and merge them or make a backup of yours and replace with this.

This version enlarges the field where we store the names we find in the search process (42 bytes now). It also encompasses the suggestions we've gathered until now in this epic journey.

Tried to comment key points. You can keep asking if you need.

Código: Selecionar todos

PROCEDURE REC_FND

PRIVATE REC2FIND, SAV_REC
PRIVATE cOldArea, cOldScreen
PRIVATE cPath

* Box border characters
PRIVATE cBorder = CHR(218) + CHR(196) + CHR(191) + CHR(179) +;
    CHR(217) + CHR(196) + CHR(192) + CHR(179)
    
* Save current position in database if search fails
*--------------------------------------------------
SAV_REC = recno()

set color to &GET_CLR
read

* Continue if escape wasn't pressed
*----------------------------------
IF LASTKEY()#ESC_KEY
*--------------------------------

   REC2FIND = space(40)

   do DISP_MSG with 'Client (include punctuation): '

   @row(),col() get REC2FIND

   read

   * Continue if the escape key was not pressed
   *-------------------------------------------
   IF lastkey() # ESC_KEY

      * Remove trailing spaces
      *-----------------------
      REC2FIND = UPPER(trim(REC2FIND))

      *-- AlxSts - Start ---------------------*

      * Save current work area
      cOldArea = Select()

      * In this version, temporary files are created
      * in the local C drive root to avoid duplicate 
      * file names on a network environment

      cPath = "C:\"

      * iF tmpTable exists, delete it and it's index file
      cString = "tmpTable"

      IF File(cPath + cString + ".dbf")
         ERASE (cPath + cString + ".dbf")
         ERASE (cPath + cString + IndexExt() )
      ENDIF

      * Summer'87 offers no support for multidimensional arrays.
      * Use a temporary table instead...
      
      * Create a name to a second temporary Table
      * used to hold the tmpTable structure definitions

      cString = Left( cString, Len( cString ) - 1 ) + "_"

      * select an empty work area
      SELECT 0

      * Create an empty table to store tmpTable structure info in the new work area...
      * The Create command leaves the newly created file open...
      CREATE (cPath + cString)

      * insert struct info...

      * field # 1
      APPEND BLANK
      REPLACE Field_name WITH "COMPNY_NAM"
      REPLACE Field_type WITH "C"
      REPLACE Field_len  WITH 25
      REPLACE Field_dec  WITH 0

      * field # 2
      APPEND BLANK
      REPLACE Field_name WITH "CASE_LNAME"
      REPLACE Field_type WITH "C"
      REPLACE Field_len  WITH 40
      REPLACE Field_dec  WITH 0

      * close struct table
      USE

      * Create tmpTable in the current work area using
      * structure definition FROM the other table...
      * The Create command leaves the newly created file open...
      
      CREATE (cPath + "tmpTable" ) FROM (cPath + cString)

      * tmpTable is now the currently selected work area... 
      * loop the entire main table (cases->)...
      DO WHILE cases->( ! Eof() )
         cString = ""
         * search LNAME first because if REC2FIND exists in both fields, LNAME takes precedence
         IF (REC2FIND $ UPPER(cases->CASE_LNAME))
            * Person's last and first names
            cString = Trim( cases->CASE_LNAME ) + ", " + cases->CASE_FNAME && assuming there is a field named CASE_FNAME (first name)
         ELSEIF (REC2FIND $ UPPER(cases->COMPNY_NAM))
            * Company name
            cString = cases->COMPNY_NAM
         ENDIF

         IF Len( cString) > 0
            * something was found. Save it...
            APPEND BLANK
            IF .Not. NetErr()
               tmpTable->COMPNY_NAM = cases->COMPNY_NAM
               tmpTable->CASE_LNAME = Upper( cString )
            ELSE
               * Error. Display some message and Exit
               do DISP_MSG with [Error writing temporary file. Press a key to exit.]
               SELECT Cases
               go SAV_REC
               RETURN
            ENDIF
         ENDIF
         cases->( DbSkip() )
      ENDDO

      * If anything was found...
      IF tmpTable->( LastRec() ) > 0

         * tmpTable is still the current selected work area. Create an index
         INDEX ON CASE_LNAME TO tmpTable

         GO TOP

         * Save the screen area used by popup window
         *---------------------
         cOldScreen = SAVESCREEN(5, 18, 20, 61)

         * Draw a box with single border
         *---------------------
         @ 5, 18, 20, 61 BOX cBorder

         * Browse records in tmp table until user
         * cancels browsing (ESC) or a record is selected (ENTER)
         *---------------------

         DBEDIT(6, 19, 19, 60, {"tmpTable->CASE_LNAME"} , "_REC_FND_", NIL, {" Select a name "})

         * Restore screen region
         *---------------------
         RESTSCREEN(5, 18, 20, 61, cOldScreen)

         * Restore previous work area
         *---------------------

         Select( cOldArea )
 
         * now, the cases table is the currently selected area
         IF LASTKEY() # ESC_KEY
            * User selected someone.
            * Save company name from tmp table...
            * This field is the index key in order # 7
            *---------------------
            REC2FIND = TRIM(tmpTable->COMPNY_NAM)

            * Seek for selected company name
            * in the original table...
            *---------------------
            * Get client index 7, ordered by company name key field
            *--------------------
            set order to 7

            * Search using the key
            *---------------------
            set exact off

            seek REC2FIND
            set exact on

            * Return to the first index
            *--------------------------

            * set order 1 as current (probably a company id field...)
            set order to 1

            * If found, put the highlight bar on the record
            *----------------------------------------------
            if !eof()

               do SCRL_TOS

            else

               * If not found, tell the user
               *----------------------------

               do DISP_MSG with [Client, ]+trim(REC2FIND)+[, not found. Press a key.]

               inkey(0)

               go SAV_REC

            endif
         ELSE
            * user cancelled...
            go SAV_REC
         ENDIF
      ELSE
         * no matches found...
         Select( cOldArea )
         do DISP_MSG with [Client, ]+trim(REC2FIND)+[, not found. Press a key.]
         inkey(0)
         go SAV_REC
      ENDIF

      * delete tmpTable...
      SELECT( "tmpTable" )
      USE

      cString = "tmpTable"
      ERASE (cPath + cString + ".dbf")
      ERASE (cPath + cString + IndexExt() )

      * delete structure info Table...
      cString = Left( cString, Len( cString ) - 1 ) + "_"
      ERASE (cPath + cString + ".dbf")
      
      * restore the cases table as currently selected work area
      SELECT( cOldArea )

   ENDIF

    *-- AlxSts - End ---------------------*
ENDIF

RETURN

*----------------------------
* User function for DbEdit()
*----------------------------

FUNCTION _REC_FND_

PARAMETERS status, fld_ptr

PRIVATE request

*
key_stroke = LASTKEY()
*

 *Table: Requests to DBEDIT() from User Function
 *----------------------------------------------------------
 *Value Description
 *----------------------------------------------------------

 * 0  Quit DBEDIT()
 * 1  Continue DBEDIT()
 * 2  Force reread/repaint and continue;
 *   after repaint, process keys, and go to idle
 * 3  Append mode (not recommended)
 *----------------------------------------------------------

DO CASE
 CASE status = 0
   * Idle. Continue
   request = 1
 CASE status = 1
   * Beginning-of-file.
   request = 1
 CASE status = 2
   * End-of-file.
   request = 1
 CASE status = 3
   * Empty database file.
   request = 0
 CASE status = 4
   * Key exception.
   IF key_stroke = 27
   * Exit
   request = 0
   ELSEIF key_stroke = 13
   * Record selected...
   * exit with temp table file pointer over selected record
   request = 0
   ENDIF
 OTHERWISE
   request = 1
ENDCASE

*
RETURN request*
* Eof --------------------------------------------------------------------------
PS: warning: not compiled or tested.
Edited: adjust sav and restscreen coordinates
[]´s
Alexandre Santos (AlxSts)
marge0512
Usuário Nível 3
Usuário Nível 3
Mensagens: 121
Registrado em: 20 Mai 2011 12:42
Localização: United States

How to SCAN substrings in a dbf - Summer 87

Mensagem por marge0512 »

Beautiful!!! Thank you! :))

The only change I needed to make was to change this line from :

cString = Left(cString, Len(cString) - 1) + "_" to:

cString = Left(cString, (Len(cString) - 1)) + "_"

I was getting a compiling error. Speaking of this line........could you explain why I needed the "_" ? I don't understand that part.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

How to SCAN substrings in a dbf - Summer 87

Mensagem por alxsts »

Hi!

Good!
marge0512 escreveu: Speaking of this line........could you explain why I needed the "_" ? I don't understand that part.
In order to create another table to store structure info about tmpTable, I needed to give it a name. It could be any name. Then I choosed to create it as "tmpTabl_". It could be "tmpTabl1" or any name conforming the DOS naming rules. If we had Clipper 5.xx, a table wouldn't be needed. Structure info could be stored in an array.

Do me a favor: change the line 86 below as indicated. We must have room for the ", " between first and last names. I edited the post to change it but this change didn't take effect.

Código: Selecionar todos

082	      * field # 2
083	      APPEND BLANK
084	      REPLACE Field_name WITH "CASE_LNAME"
085	      REPLACE Field_type WITH "C"
086	      REPLACE Field_len  WITH 40   ------------------> REPLACE Field_len  WITH 42
087	      REPLACE Field_dec  WITH 0
Be happy!
[]´s
Alexandre Santos (AlxSts)
marge0512
Usuário Nível 3
Usuário Nível 3
Mensagens: 121
Registrado em: 20 Mai 2011 12:42
Localização: United States

How to SCAN substrings in a dbf - Summer 87

Mensagem por marge0512 »

Thanks! Here is something else I don't understand, if you don't mind explaining again:

APPEND Blank
REPLACE Field_Name with "COMPNY_NAM"
REPLACE Field_Type with "C" <------------Why value "C"? What does that mean.
REPLACE Field_Len with 25
REPLACE Field_Dec with 0 <------------Also, the same for this value.

I understand the concept of this code but I don't know why the two lines I pointed out were used with those values.

Also, with *Close struct table
*--------------------
USE <-----------Do I need to be concerned with EXCLUSIVE or SHARED?

And last..........I keep forgetting to ask this one:

DBEDIT(6, 19, 19, 60, {"tmpTable->CASE_LNAME"},"_REC_FND_", NIL, {"Select a name "}) <---------Why does DBEDIT use
{"tmpTable->CASE_LNAME"} and not
{"tmpTable->COMPNY_NAM"} at all?
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

How to SCAN substrings in a dbf - Summer 87

Mensagem por alxsts »

[]´s
Alexandre Santos (AlxSts)
marge0512
Usuário Nível 3
Usuário Nível 3
Mensagens: 121
Registrado em: 20 Mai 2011 12:42
Localização: United States

How to SCAN substrings in a dbf - Summer 87

Mensagem por marge0512 »

Hi!

When I compile in Harbour, I do not receive any errors but I am trying to compile in Summer87 and I receive a mismatch error on this part:

cPath = "C:\"

cString = "tmpTable"

IF File(cPath + cString + ".dbf")
Erase (cPath + cString + ".dbf")
Erase (cPath + cString + IndexExt())
ENDIF

cString = Left(cString, (Len(cString) - 1)) + "_"

SELECT 0

CREATE (cPath + cString) <----------------------Point of error.

I've tried several things but anything I tried did not help.

Thanks in advance!
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

How to SCAN substrings in a dbf - Summer 87

Mensagem por Pablo César »

Please note at line CREATE (cPath + cString), probably in Summer does not accept Path. Try CREATE cString
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Responder