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 TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Automatically append last value + 1 into the textbox 1

Status
Not open for further replies.

Filip Brnic

Programmer
Dec 25, 2023
42
RS
Long time no see, I've stumbled upon a roadblock, I have no clue on how I would exactly do this because I never used this syntax

(table: akcionari, field:rednibr)

I have a textbox1 in my form, I have a button that appends blank and lets me insert values into textboxes, but my textbox1 is a number, basically index number, so if there is no records and you append a new one it should be 1, then if the last record was 1 the one after should be 2,

I had an idea that you could just do something like this :

command1.click event
Local x
go bottom
x = VAL(akcionari.rednibr)
thisform.text1.value = X+1
but it doesnt work.
Its simple but i have no clue how to do it :).
IF someone could get me going on this or do it for me so i learn this forever.

BTW, there were errors about function type, count being invalid, but my rednibr field is a numeric (2) so i had no clue what that was about.
hope someone can help!
 
Well,

long story short, what you do is have an INTEGER AUTOINC data type field in the table, and that does the counting.

Without more information of your table structure it's hard to tell why you get an error. My guess is that rednibr must be a char field, because VAL() is used to convert a string that represents a number into that number in the numeric date type, i.e. "1" is turned into 1.0 - if you think the difference is .0, no the difference is going form char to float, VAL does also turn "abc" into 0.0 or any string that is not representing a number, it also just ignores things after a number, so "3.5 inch" is turned into 3.5.

(Edit: That's not true, you said rednibr is an numeric type and so...)

VAL(rednibr) will not just be generous to you and say, "oh, I can just return that input back, as it already is a number". Instead, it throws the error "Function argument value, type, or count is invalid" because of the type being invalid. VAL can only be passed in strings also known as char type fields, memos are also strings, but although it would be feasable and is straight forward for it to just be the function f(x): x-> x, ie. just returning the input as its output, when the input already is a number, it is exlplicitly constructed to give back a number only when you pass in a string value.

Generally speaking, you have to program by the definitions of the programming language.
Sepcifically speaking VAL doesn't accept numbers as input.

And all that in short: As rednibr already is a number, why on Earth do you process it with a function at all, if you want a number and already have a number? There's nothing to do with the number, but provide it as is plainly as akcionari.rednibr.

Chriss
 
Chris, im trying to achieve the following, i have textboxes that become readonly=.f.
So you can insert values names surenames whatever, but i want the rednibr to automatically go +1 everytime because i dont want people inserting it on their own, otherwise you couls have literally two of the same numbers and that wouldnt make much sense, having a Worker#1 and a worker#1, i want the commandbutton to on click , go to the last record in selected table akcionari field rednibr, and if that number is 11 it sets the textbox value in the form to 12.
 
I saw that thank you, do you know where i could read a little about that in the fox help menu?
 
This time you already know enough to "discover" this as you already did create a table, didn't you?

You're familar with the table designer. I said integer autoinc is a data type, so it's simply listed in the selections you have for each filed about which data type they should be:
autoinc_tabledesign_rwrqwf.png

There's even that sectgion to the right, where you could make it count in steps of 2 or begin counting at 1000, if you like, starting at 1 and incrementing by 1 is the default.

And if you absolutely want to read about autoinc in the help, it's always bound to Integer autoinc, but search for autoinc and these are the search results:
autoinc_help_ulyfyq.jpg


Chriss
 
Hey Chris, i have some unfortunate news for this. Im undergoing some training and my mentor told me to create this using a code, there is a button we have in the form that lets us append information, he wants me to have it there, he mentioned something with recno if i recall properly, he wants me to go to the last record and add +1, he has this in his code he sent me as an example
But it seems hard and i cant really understand why it doesnt work in my code
IF you wanna know about the table integrity here is the code i used to create a table

IF !FILE ("akcionari.dbf")
CREATE TABLE Akcionari (RedniBr I(2), Ime c(10), Prezime c(20), Mail c(45), ZiroRacun c(20), Grad c(50), Okrug c(50), Procenat F(6,2))
ELSE FILE("akcionari.dbf")
USE akcionari IN 0
SELECT akcionari
ENDIF

and here is his code for doing what integer autoinc does,
ofcourse you can replace opstine.sifra with akcionari.rednibr and cursor manji is just a random cursor, but even tho i replaced all of that with my information it didn't work for some reason...
calculate max(val(opstine.sifra)) to aaa
aaaa=subst(right(str(aaa),3),3,3)
if aaaa='9'
sele * from opstine where sifra!=aaaa into cursor Manji
calculate max(val(Manji.sifra)) to aaa
bbb=aaa+1
wbroj=right('000'+alltr(str(bbb,3)),3)
sele opstine
else
bbb=aaa+1
wbroj=right('000'+alltr(str(bbb,3)),3)
endif
append blank
thisform.Text1.value=wbroj
 
I really can't help you if you even only halfways recall what you were told to use and do. But I already explained in all detail what was wrong with your usage of VAL(). You simply have not to use it in your case.

Besdes, this forum explicitly has the policy to remove posts about coursework or even remove members come heer to let their homework be done. I know you're not that guy, you're asking to understand things, but I can't help you if you don't understand explanations that are already clear to the point as much as they can be or at least, if you don't understand them, point out what of them you didn't yet get. Your evasive actions of putting new things on the table is also not helpful, as it just means all the effort to teach you something is lost and ignored. That's not how you motivate people to help you learn what you need to know.

Chriss
 
Filip,

one chapter after the other. Your code is almost complete:

Code:
Local x
go bottom
x = VAL(akcionari.rednibr)
thisform.text1.value = X+1

This would work, if you just would comprehend what I told you about the VAL function in my first answer to you. If you don't understand something about that, please point out what you didn't understood.

Chriss
 
I think there is a misunderstanding. To retrieve the contents of a field, no function is needed. So x=akcionari.rednibr is sufficient to assign the content of the field to x.
However, for a textbox, '.value' should be used to retrieve the content.
Georges.
 
True, coppensg

There also is a natural language barrier, besides Filip showed where he got the idea to use VAL() from the convoluted code example: calculate max(val(Manji.sifra)) to aaa. In that case Manji.sifra must have been a char field.

Filip has last logged in on Friday, likely he hasn't seen the last answers yet, or already got it and won't come back until the next problem. Anyway, part of the problem seems to be the code he learns from is convoluted already and not the best basis to learn something.

Chriss
 
Filip, your mentor is wrong here. If there is any possibility that more than one person will be using this application at the same time, finding the largest value and incrementing it is dangerous, because two people could do that at the same time, and you'd end up with two records with the same value.

As for using RECNO() for this, that's also dangerous because records can be deleted over time and thus, their record numbers can change.

Integer (AutoInc) is the best way to do this. The second best way, which we used to use before we had Integer (AutoInc) is to store the next available number in a different table. (Normally, you'd have a record for each table, containing the next available value.) Then, we you need a number, you find the right record in that table of next available values, lock that record, grab the value, increment that record, so it's ready for the next record, and then unlock.

But that's a lot of unnecessary work if you're in a version of VFP that supports autoincrementing integers (which I think is VFP 8 and later).

Tamar
 
That's why I mentioned autoinc integers from the start.

If Filips mentor asked them to do this with their own code, perhaps he has in mind teaching how this is insufficient in the next lessons, we don't know. Maybe Filips is asked to do this in a legacy Foxpro version, but it's true even then you would not just go bottom and add 1 to the max value you expect there to be in the bottom record - sorted by the numeric sequence field.

One other thing that's backwards despite not locking a record for this, getting and updating the max value from a dedicated separate table to maintain the max count is to then not put the max+1 directly into the DBF after the append blank, but set a textbox.value to it. Even if that's bound to the field by controlsource, the way into the DBF then is indirect only.

And without any precautions of locking records, even better an flock on the table, you risk what Tamar says, double entries of the same number.

The given code has a char field as basis, not an integer (there doesn't exist a type I(2), btw, it's simply int or integer or just I) and the string expression right('000'+alltr(str(bbb,3)),3) points out that this is a char(3) field with numbers that have leading zeros and go from '000' to '999' only. An integer, in contrast, can go up to about 2 billion. It's always straight forward to use numeric fields for numeric data, and then, when you need leading zeros, add them for display or report output or whatever, even older versions of VFP or Foxpro before the "visual" age had the PADL() function for that.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top