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

Placing a field of records in a messagebox. (VFP 9.0 SP2) 2

Status
Not open for further replies.

T17Rax

Technical User
Jun 11, 2015
39
GB
Hi all,

First time posting on here. I'm teaching myself FoxPro and giving myself little tasks to do so I've a better understanding on how VFP works, but unfortunately, I'm stuck on a problem.

I've got a DBF which is like a user list. There's a field listed as "Cardno" that contains a pin number per user. X amount of records have been Marked for deletion which means that the pin number can be given to someone else. I'm trying to generate a quick list of the pin numbers from the deleted records, so I can use the pin numbers again. Preferably, I'd like to view them in a message box.

The code I'm working on at the moment is shown below. It's clearly not giving me the result I'm after. Would anyone mind giving me a hand or a guide where I'm going wrong and what to do, so to speak?

Any help is appreciated.

Many thanks!


[[[[
cd\cashless
SET SAFETY ON
SET EXclusive ON
USE id

COUNT for DELETED() TO Pinlists
MESSAGEBOX("Deleted: " + ALLTRIM(STR(Pinlists,10,0)))

DIMENSION Pins(1,14)
COPY TO ARRAY Pins FIELDS Cardno FOR DELETED() = .T.

MESSAGEBOX("Pin List: " + ALLTRIM(STR(Pins,5,0))
]]]]

p.s. The square brackets are just to seperate the code from the post!
 
If you want to use a deleted record again, you shouldn't delete it at all. Instead you should add a logic field, and call it for instance Reusable. Set this field to true instead of deleting the record. A deleted record should be considered as gone forever. If you later decide to switch to SQL Server to store your data, you will need to use this approach, since there a deleted record is not recoverable.

The code you presented, minus the last two lines, will be like this:

[pre]Select Cardno from yourtable where reusable into array laPins
Messagebox('Deleted: ' + transform(alen(laPins,1)))[/pre]

Here's the last part:

[pre]lcText = 'Pin list: '
for lnX = 1 to alen(laPins)
lcText = lcText + laPins(lnX) + ','
Endfor
lcText = left(lcText,len(lcText)-1)
messagebox( lcText)[/pre]

 
I see. I never thought that far ahead about record deletion! It would make sense to have a logical field.

I've ran the prg and it works! So, thank you! :)

I'm going to attempt to study the code and learn what's just happened haha.

Thanks again!
 
Hi VibrantSeeker and welcome to the forum.

I agree with TBleken's advice about not using deleted records in this way, but I would go one step further: Don't try to re-use your user IDs. Even after the original user has been deleted, it could lead to all sorts of complications. Better to give each user a new ID. Unless you've got a gigantic number of users, you're never going to run out of numbers.

I'll just add a couple of other points:

First, I wouldn't normally use SET SAFETY ON or SET EXCLUSIVE ON in a real program, unless there is some special reason to. With SAFETY on, VFP will display a message asking the user to confirm a file deletion or overwrite. The user won't know what to answer, and will either panic or will choose not to confirm, which is not what you want. With EXCLUSIVE on, other users will be locked out of viewing or editing the file. Of course, this doesn't matter if you are just experimenting, but keep it in mind as you progress.

Next, if you want to display a list within a messagebox, it's a good idea to separate the items with CHR(13) so that they appear on separate lines. This is not essential, but it does make the list more readable. If you've got a very long list, you might want to write it to a text file or even a report. To write to a text file, create the variable as you are already doing (that is, lcText), then user STRTOFILE() to get it into a file. As for reports .... well, let's leave them for another day.

Finally, you said "The square brackets are just to seperate the code from the post!" A better way to do that is to use the
Code:
 tag, or the corresponding button on the toolbar (just above the box where you write your post). 

Good luck with your learning, and come back when you have more questions.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

[url=http://www.ml-consult.co.uk/foxstuff.htm]Visual FoxPro articles, tips and downloads[/url]
 
Welcome from me, too. Much is already said.

I just want to ask about the pin numbers, are these the primary key of the users (do you even know that concept of databases?) The name pin is typical for magnet stripe id cards, often limited to 5 or even 4 digits, so reusability is surely desirable, if the deletion of an id with it's pin is in conjunction with the expiration of the physical id card. Anyway, I know those magnet stripes have much info to identify the card holder not only by the pin, which isn't even stored there. If it was, a stolen card would reveals the "password" to use it. No, that works much different.

Anyway, before we go off topic, if we talk about the database primary key, indeed a reuse of a user id is NOT desirable, as any undeleted data related to some deleted user would be revivied and related to the new user, if he is assigned a recycled id. That's like getting a mail box with tons of mails belonging to the previous user of the mail address. You laugh? This happened to me, fortunately no one got hands on my mails but vice versa I got a mail address which obviously belonged to someone before. I'm not talking of getting spam or other mail to the address, just because it was known before, I talk of mail that was in the inbox just seconds after requiring the mail address having been sent and revceived months ago. I deleted all this, but I also know I will have to do so, before I unsubscribe with that mail offer.

Last not least to explain your errors:

[pre]DIMENSION Pins(1,14)[/pre]
I guess your record has 14 fields, why do you dimension the result array? You don't know how many deleted rows you have yet, so any dimensioning is a guess. You expect it to be expanded? It may well be expanded, it indeed would be generated as needed by COPY TO, so you best not generate it at all. But why 1 row with 14 columns?

[pre]COPY TO ARRAY Pins FIELDS Cardno FOR DELETED() = .T.[/pre]
You copy just one field, so that result array will have one column only, even if the Cardno field is one of 14 of your table, you only copy that field into the first and only column of the result.

[pre]MESSAGEBOX("Pin List: " + ALLTRIM(STR(Pins,5,0))[/pre]
I don't see your thought here, 5 may be the pin length, at least you then have 100,000 pins, but you don't address an array without specifying an element index, eg Pins[1,1] to Pins[1,14] are available initially. Addressing the array with just its name, you get the first element only. If you store "xxxxx" to Pins, this would store this to all array elements, but that's a specialty for writing and assigning values not working for reading a whole array. For reading all array elements you need a loop iterating all elements.

I hope this helps you understand, what you did wrong.

I'd even just select cardno from yourtable where deleted(). You need SET DELETED OFF for seeing deleted rows from a query, the other settings are not influencing this, but were already addressed by Mike. And it's no good idea in the general case to query with DELETED OFF, you get all kinds of meshed records from both deleted and undeleted rows when joining tables, even if you use DELETED(aliasname). It's complicated to explain, but the only good setting while querying data is SET DELETED ON.

Bye, Olaf.
 
I would like to add that you should bear in mind that the MessageBox() can only display a relatively small number of characters.

You might be better off doing a number of other things - perhaps display your list in a notepad window, use an editbox on a dialog
form, pop the results in a cursor and show that in a grid on a modal form... with VFP the options are endless.

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are not good for you.
 
Hi again people.

Apologies for the delayed reply and thank you for all your comments. Typically, I'm learning basic coding to try and get things running.

Olaf, thank you for pointing out the DIMENSIONS bit. I must have misread somewhere on defining array dimensions. I was looking for 1 field and 14 rows. NOT 1 row and 14 fields. The message box was just there for a quick output. If there was a lot more records to view, I would certainly use a spreadsheet or other text file of some form.
Indexing I'm not fully aware of so, the primary key is not included in the file. I understand that searches in a table are guided by an index tag but I do believe it's something that I may need to read more on as it could prove extremely reliable!

The SET commands are there for precaution. It would be wise to have deleted ON to keep things tidy!

I'll get there once day.
Thanks guys once again!

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top