Página 7 de 9
How to SCAN substrings in a dbf - Summer 87
Enviado: 29 Jan 2013 13:33
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.
How to SCAN substrings in a dbf - Summer 87
Enviado: 29 Jan 2013 13:49
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.
How to SCAN substrings in a dbf - Summer 87
Enviado: 29 Jan 2013 14:46
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?
How to SCAN substrings in a dbf - Summer 87
Enviado: 29 Jan 2013 14:55
por marge0512
The first names are still not showing. I'm debugging now to find out what is going on.
How to SCAN substrings in a dbf - Summer 87
Enviado: 29 Jan 2013 16:07
por alxsts
Hello!
If you want, post the code again.
How to SCAN substrings in a dbf - Summer 87
Enviado: 29 Jan 2013 16:57
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......
How to SCAN substrings in a dbf - Summer 87
Enviado: 29 Jan 2013 17:35
por alxsts
What's the length of both fields concatenated?
How to SCAN substrings in a dbf - Summer 87
Enviado: 29 Jan 2013 17:40
por marge0512
I believe together it is a total of 40. They usually allow 25 for the last name and 15 for the first.
How to SCAN substrings in a dbf - Summer 87
Enviado: 29 Jan 2013 19:47
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
How to SCAN substrings in a dbf - Summer 87
Enviado: 30 Jan 2013 14:01
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.
How to SCAN substrings in a dbf - Summer 87
Enviado: 30 Jan 2013 15:21
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!
How to SCAN substrings in a dbf - Summer 87
Enviado: 30 Jan 2013 18:08
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?
How to SCAN substrings in a dbf - Summer 87
Enviado: 30 Jan 2013 20:36
por alxsts
How to SCAN substrings in a dbf - Summer 87
Enviado: 07 Fev 2013 14:16
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!
How to SCAN substrings in a dbf - Summer 87
Enviado: 07 Fev 2013 14:25
por Pablo César
Please note at line CREATE (cPath + cString), probably in Summer does not accept Path. Try CREATE cString