Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

APPEND BLANK is not realtime... Please help. 3

Status
Not open for further replies.

Mandy_crw

Programmer
Jul 23, 2020
578
0
16
PH
Hi everyone... am i missing something in the codes? it does not add record or i mean it does not append realtime, it appends new record when the application is closed.... Please help... Thanks and God Bless....


SELECT 3

araw = CDOW(DATE())
notif = tsulat.ctr - 1
x = " "

if notif = 0 or notif = 2
x = "IN"
ELSE
x = "OUT"
ENDIF

APPEND BLANK
REPLACE rek.idnum WITH this.value
REPLACE rek.time WITH DATETIME()
REPLACE rek.lname WITH this.parent.text2.value
REPLACE rek.kol WITH x
REPLACE rek.dey WITH araw

this.value = " "
this.parent.text2.value = ""
this.Parent.text3.value = ""
RETURN 0
 
Hi Mandy,

We do not see when and how you open table rek.
Maybe for quick test try after last replace
to close and reopen the table
Use in select("rek")
Use rek in 0 alias("rek").

Hope this helps

 
Hello Mandy,

Are you using table buffering?

Also, you may want to consider using SQL for this. Good practice to set property values to memvars first. Example:

liIDnum = this.value
ltDateTm = DATETIME()
lcLName = this.parent.text2.value

INSERT INTO rek (idnum, time, lname, kol, dey) ;
VALUES (liIDnum, ltDateTm, lcLName, x, araw)

The benefits are: (1) Much faster and cleaner (2) You do not have to select the workarea (e.g. SELECT 3) and (3) Good oportunity to start learning SQL - you can do amazing things with it
 
Ljupce Zagorac hi... i've opened the three tables in the initialization routine... thanks so much...
Hi vernpace ok i'll try it now, i'll try to change it and see if it works well with me... (i'm an old programmer of foxbase) Thanks so much for the tip, i'll keep you posted... God bless....
 
By the way vernpace i dont know what is table buffering....
 
Many,

Given that you don't know what buffering is, then the chances are you are not using it. It is not something you can do by accident.

A quick solution might be to execute [tt]FLUSH[/tt] after the updates. That might fix it, but it is not very satisfactory, because it doesn't tell you what caused the problem in the first place.

I suspect that the root of the problem is the very first line: [tt]SELECT 3[/tt]. It is considered very bad practice to refer to work areas by a numbre. Much better to use the table alias. We have no way of knowing what that alias is, but it might be [tt]rek[/tt], since that is what you are using in the [tt]REPLACE[/tt] commands. If that's right, then do [tt]SELECT rek[/tt] rather than [tt]SELECT 3[/tt].

This is important because the [tt]APPEND BLANK[/tt] always applies to the current work area. But your [tt]REPLACE[/tt] commands are specifically updating fields in [tt]rek[/tt].

It would be better to write the [tt]REPLACE[/tt] as follows:

Code:
REPLACE ;
  rek.idnum WITH this.value, ;
  rek.time WITH DATETIME(), ;
  rek.lname WITH this.parent.text2.value, ;
  rek.kol WITH x, ;
  rek.dey WITH araw [b]IN Rek[/b]

That way, there can be no doubt about which table you are updating.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mandy,

Just to go back to the question of bufferieng ....

I don't think this will be necessary, but you could try the following before the [tt]APPEND BLANK[/tt]:

Code:
CURSORSETPROP("Buffering", 0, "rek")

This will turn buffering off, on the off-chance that it had got turned on. You could also go to Tools / Options / Data, and set Buffering to "Off".

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I don't see how else a record would stick in memory until the application and so all tables close but buffering, what else could cause this behavior, Mke?

Using Insert will help, I'd check, whether RECNO('rek') is negative, because that's a sure sign of a buffered record. VFP then does not know yet, what record number the record will get once the buffer is eventually stored in the DBF, so it will locally (in the buffer) assign negative numbers temporally.

Besides that, you could check whether CURSORGETPROP('Buffering','rek') is larger than 1, alas, it won't tell you about the buffering of the new record. There's also getfldstate() to determine the buffer status, but nothing is as simple as checking for a negative record number.

PS: APPEND BLANK is often coming up, developers seem to not let go of it. I also appreciate it as the simplest way to get a new, blank record no matter what fields a table has. It's not a no go, in the situation you have, updating the blank record with replace, you better do an SQL Insert.

Chriss
 
Chris, I completely take your point about buffering. It does seem the most likely explanation. I just hesitated because it is unlikely that Mandy could have enabled buffering without knowing. Then again, I suppose it could have been done in some inherited or imported code.

Mandy, another alternative would be avoid the issue completely by using SQL code. So, instead of your [tt]APPEND[/tt] and [tt]REPLACE[/tt]s, you could try this:

Code:
INSERT INTO rek ;
 (idnum, time, lname, kol, dey) VALUES ;
 (this.value, DATETIME(), this.parent.text2.value, x, araw)

Just one other small point, "time" is not a great name for a field. It probably won't cause any problems in this case, but as it is a function name in the Foxpro language, it would be wise to avoid using it for a field or a variable.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
hi everyone...Ljupce Zagorac vernpace Mike Lewis Chris Miller first of all id like to say thank you to all of you... thanks for your help.... but i tried everything, none of these worked... i spent almost a day now figuring it out... and up to now it still not working... ive tried also eveything that i know aside from your suggestions... its just keep on appending when the app is closed... if i may add the APPEND BLANK is inside procedure text1.valid(), is there a connection to this problem... thanks again... God bless...
 
i may add the APPEND BLANK is inside procedure text1.valid()

Now that's interesting. I see you are RETURNing 0 from the Valid. Do you realise the returning 0 is the same as returning .F., which means that the control cannot lose focus? That in itself doesn't mean that the append and replaces won't succeed, but it does suggest that something is fundamentally wrong.

Try changing [tt]RETURN 0[/tt] to[tt] RETURN .T.[/tt] and see what effect that has.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Mandy,

Reading your code I assume that your GUI is a form. You may try

Code:
...

APPEND BLANK
REPLACE rek.idnum WITH this.value
REPLACE rek.time WITH DATETIME()
REPLACE rek.lname WITH this.parent.text2.value
REPLACE rek.kol WITH x
REPLACE rek.dey WITH araw 

ThisForm.Refresh()

....

hth

marK
 
What do you actually check, do you use the table on another workstation and it's still missing there?

Again, it all speaks for buffering, so please tell us whether recno() is negative or not directly after the APPEND BLANK. I agree with Mike you surely don't accidently turn on buffering, but inherited code might set it for all workareas by setting it for workarea 0 and another possibility IIRC is a dataenvironment setting, which again will affect all workareas.

The valid event usually is the one you tell VFP to accept the changed value, so returning 0 or .f. can be the simple reason. When you quit the app you finally exit the control and save changes.


Chriss
 
Mark has made a good point. Mandy, is it possible that the changes have in fact been made, but you are simply not seeing them in the form? If so, then it might be enough to refresh the form, as Mark suggested.

That said, I'm still worried about you doing all this in the Valid, especially as the Valid is returning 0. I'm not sure what the effect would be of refreshing a form in the Valid event. Can you move the code somewhere else: say, to a button on the form - if only to see if that causes the problem to go away.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
hi chris & Mike.. what the valid event does is take the idnumber of the employee/s, once found it displays all info about the idnumber, then gets another, thats why it always return 0 at the end so that it will get another idnumber to show another info... i really dont understand why i have to exit before it appends? I mean in the code it executes everything excepts the append. For the buffer chris i really dont know how to use buffer...the refresh didnt work... i am still figuring it out up to now, what could have been wrong.... and how to correct it... thanks for your help.... i really appreciate it.... God Bless....
 
Hi Mandy,

You code IS working, but is not very user-friendly, since you "hide" the appended records. Let me try to explain what I read from your code.

1) You append a record

APPEND BLANK
REPLACE rek.idnum WITH this.value
REPLACE rek.time WITH DATETIME()
REPLACE rek.lname WITH this.parent.text2.value
REPLACE rek.kol WITH x
REPLACE rek.dey WITH araw

then 2) you immediately blank out the textboxes

this.value = " "
this.parent.text2.value = ""
this.Parent.text3.value = ""
RETURN 0

Hence the question: where do you show the appended records?

If you want to stick with your approach to blank out the textboxes right after having appended a record, you might want to adapt it a little bit (please see code snippet below - especially the cmdSave.Click() part)

Code:
PUBLIC go_Form

go_Form = CreateObject ("frmForm")

go_Form.Visible = .T.
go_Form.Show

READ Events
CLOSE ALL
CLEAR ALL


DEFINE CLASS frmForm As Form
  Width = 450
  MinWidth = 450
  MaxWidth = 450
  Height = 360
  MinHeight = 360
  AutoCenter = .T.
  ShowTips = .T.
  Caption = "Append Record"
  
  	ADD OBJECT txtCode as TextBox WITH ;
  		Top = 12, Left = 12, Width = 60, Height = 24, InputMask = "999", ToolTipText = "Format 999"

  	ADD OBJECT txtName as TextBox WITH ;
  		Top = 12, Left = 84, Width = 150, Height = 24

  	ADD OBJECT txtGender as TextBox WITH ;
  		Top = 12, Left = 246, Width = 48, Height = 24, Value = "M", Inputmask = "M,F,X", Format = "M", ToolTipText = "M - F - X"


	ADD OBJECT grdNames as Grid WITH ;
		RecordSource = "csrDemo", ColumnCount = -1 , Visible = .t., Top = 48, Left = 12, Width = 426, Height = 258, Anchor = 15, ReadOnly = .T.

	ADD OBJECT cmdSave As CommandButton WITH ;
		Width = 90, Height = 30, Left = 84, Top = 318, Caption = "Save Record", Anchor = 6
		
		PROCEDURE cmdSave.Click()
			IF EMPTY(ThisForm.txtCode.Value) OR EMPTY(ThisForm.txtName.Value)
				= MESSAGEBOX("You have to enter a valid Code/Name", 16, "Add record")
			
			ELSE
				APPEND BLANK 
					replace cCode WITH ThisForm.txtCode.Value, ;
						cName WITH ThisForm.txtName.Value, ;
						cGender WITH ThisForm.txtGender.Value
				
				WITH ThisForm
					.txtCode.Value = ""
					.txtName.Value = ""
					.txtGender.Value = ""
				ENDWITH 
				
				ThisForm.Refresh()
			ENDIF 
		ENDPROC 

	ADD OBJECT cmdExit As CommandButton WITH ;
		Width = 60, Height = 30, Left = 12, Top = 318, Caption = "Release", Anchor = 6

	PROCEDURE Load()
	
		CREATE CURSOR csrdemo (cCode C(3), cName C(10), cGender C(1))
		
		INSERT INTO csrdemo VALUES ('001','Henry','M')
		INSERT INTO csrdemo VALUES ('011','Jenny','F')
		INSERT INTO csrdemo VALUES ('004','Eve','F')
		INSERT INTO csrdemo VALUES ('005','Lauren','F')
		INSERT INTO csrdemo VALUES ('009','Bob','M')
		
		LOCATE 

	ENDPROC
	
	PROCEDURE cmdExit.Click()
		CLEAR Events
		ThisForm.Release

	ENDPROC
	
	PROCEDURE grdNames.Init()
		WITH This
			.Column1.Header1.Caption = "ID"
			.Column2.Header1.Caption = "Name"
			.Column3.Header1.Caption = "Gender"
		ENDWITH 
		
	ENDPROC 
  
	PROCEDURE Destroy()
		CLEAR Events
		ThisForm.Release

	ENDPROC
ENDDEFINE

hth

MarK
 
You don't need to know how to use buffering, you likely have it turned on unintentionally, no matter that Mike first thought without knowing it you surely don't use it. It can be on, because the code generallyy put it on somewhere.

So, please, just put Messagebox(Recno()) after the APPEND BLANK and tell us whether that's negative or not. Then we know we either have to address turning buffering off or the problem is something els. And this would really help to help you, as it cut's the possibilities down. So pleaase shine a light into our darkness by answering our questions to help to help you.

Chriss
 
Hi mjcmkrsr... im sorry but i dont intend to show really the appendid records... i just want to record the time when the idnumber was entered... and after i should initialize text1 again to get another id for the next employee, hence the space to the three textboxes... Thanks...

Hi Chrismiller... it returned a positive number.. (7)


Thanks so much....
 
Okay, that's interesting, then the record is added to the DBF. Quite a low number.

If you then BROWSE you should see the record.

Just notice what MarK said: After you store the record, you empty the textboxes, so you don't display the new record.

If the textboxes controlsources are the fields, you also do something you surely don't want to do: You store the data at first, and then blank the new record by blanking the textboxes. If you use ontrolsources this is a two-way binding, you show the DBF data and edits are stored in the current record. In that case all you need to do is APPEND BLANK to get a new blank record that's also becoming the active record and is displayed in the textboxes, so you don't need to empty them, the new record does that when you do Thisform.Refresh(). As that didn't work I assume you don't use the controlsources of the textboxes.

And once more: Valid is the event you tell VFP the record data is, Well, valid, ie correct and you allow to store it. When you always return 0 to stay within the control you never allow saving the data. Even without buffering setting the textbox itself isn't storing back its current value into the DBF, you should then have the data you put in with REPLACE after the APPEND BLANK.

Instead of RETURN 0 in Valid, do This.SetFocus() in the LostFocus event. But have an exit strategy to allow the focus to finally change.

Chriss
 
Thanks chris.... ill have to study this well, since i am an old programmer of foxbase... so some commands are kind o new to me... i.e. setfocus, God bless chris...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top