Qbasicnews.com
March 30, 2020, 09:57:15 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Back to Qbasicnews.com | QB Online Help | FAQ | Chat | All Basic Code | QB Knowledge Base
 
   Home   Help Search Login Register  
Pages: [1] 2 3
  Print  
Author Topic: Another Question - File opening and writing  (Read 6863 times)
casonon
Member
*
Posts: 28


« on: June 04, 2003, 12:50:35 PM »

Hello all,

1st let me say thanks to all of those that have helped me with my previous posts.

Now onto my new problem.   :Huh:  
With the program I am writing, I would like to be able to open what I call a running file and have the program add to it.  Basically it would work like this.  I will ask the user several questions.  For this example lets us name, age.  After I have the information, I want to be able to open a file that has the same information from other people and then add the new information to the list.  And then have the computer assign the person a number based off a number in the opened file.  So if the user is the 10th person entering the information, the program would assign him the number 10 and the next person to use the program would get assigned 11.  

I would like the file to look something like this.
""""""""""""""""""""""""""""""""""""""""""""""""
Number (assigned)                  Name                  Age
**                                 Chris          22
ect....

""""""""""""""""""""""""""""""""""""""""""""""""

Also, I will need to be able to search this file for key words later on and list any information based on that search.

So if I search for the person with the number 15, I will get the following information

Number - Name - Age

Also if I search for anyone with the age of 22, I would recieve all persons of that age in the above format.

Then I need to save the file and exit the program.

Everytime this program is run I need it to open and get the last number added and then assign the next number in order.  I would like it to allow alphanumerics.  So the first number would start with A1 and the go to A2 and so on.

This might sound confusing, please if you have questions let me know.  I would appreciate any input.
Logged
toonski84
__/--\__
*****
Posts: 2567



« Reply #1 on: June 04, 2003, 05:43:21 PM »

I might be confused as to what you're asking, but here's a way to save a simple flatfile database in qb.

Code:
TYPE data
  name as string * 15 ' this string can only be 15 chars long
  age as integer
  petsname as string * 15
END TYPE

' to write a record
DIM recordx as data
recordx.name = "Jane Doe"
recordx.age = 25
recordx.petsname = "Jofers"

open "datafile.dat" for binary as 1
  seek lof(1) + 1
  put #1, , recordx
close 1

' to retrieve records

dim records(100) as data ' max: 100 entries.

open "datafile.dat" for binary as 1
  do until eof(1)
    get #1, , records(n)
    numrecords = numrecords + 1
  loop
close 1


of course, this is off the top of my head and may not work.  but that's how a flatfile db ought to be done in qb.
Logged

i]"I know what you're thinking. Did he fire six shots or only five? Well, to tell you the truth, in all this excitement, I've kinda lost track myself. But being as this is a .44 Magnum ... you've got to ask yourself one question: 'Do I feel lucky?' Well, do ya punk?"[/i] - Dirty Harry
Phydaux
Senior Member
**
Posts: 200



« Reply #2 on: June 04, 2003, 11:03:37 PM »

Quote from: "toonski84"
TYPE info
  personsName as string * 15 ' this string can only be 15 chars long
  age as integer
  petsname as string * 15
END TYPE

' to write a record
DIM recordx as info
recordx.PersonsName = "Jane Doe"
recordx.age = 25
recordx.petsname = "Jofers"

open "datafile.dat" for binary as 1
  seek #1, lof(1) + 1
  put #1, , recordx
close 1

' to retrieve records

dim records(100) as data ' max: 100 entries.

open "datafile.dat" for binary as 1
  do until eof(1)
    get #1, , records(n)
    numrecords = numrecords + 1
  loop
close 1
Added and ammended parts of code. (NAME and DATA are reserved.)

If you wan't to search the file, without loading the whole file into an array, you could use this.
Code:
'this code assumes you have alread defined recordx

OPEN "datafile.dat" FOR BINARY AS #1
   numberOfRecords% = LOF(1) / LEN(recordx)
   FOR record% = 1 to numberOfRecords%
      GET #1, record%, recordx

      'each of the strings are saved as 15 characters,
      'so it would normaly equal "Jane Doe       "
      IF RTRIM$(recordx.personsName) = "Jane Doe" THEN
         REM do what you want with it
      END IF
   NEXT record%
CLOSE #1
You will obviously have to add in your own parts of code to decide what part of the record to search, what to search for, and what happenes when you find something.
Logged

url=http://www.spreadfirefox.com/?q=affiliates&id=60131&t=79][/url]
END OF LINE.
toonski84
__/--\__
*****
Posts: 2567



« Reply #3 on: June 04, 2003, 11:05:01 PM »

thanks -- i forgot about that Tongue

quick note:  numrecords is the number of records after the database has been loaded.
quick note:  I noticed you dont load the entire thing.  gotcha.
Logged

i]"I know what you're thinking. Did he fire six shots or only five? Well, to tell you the truth, in all this excitement, I've kinda lost track myself. But being as this is a .44 Magnum ... you've got to ask yourself one question: 'Do I feel lucky?' Well, do ya punk?"[/i] - Dirty Harry
Neo
Na_th_an
*****
Posts: 2150



« Reply #4 on: June 05, 2003, 07:04:39 AM »

lol
Typed by heart right?
Logged
casonon
Member
*
Posts: 28


« Reply #5 on: June 05, 2003, 07:40:48 AM »

I think you guys understand what I want, But can someone please explain to me what is writen in the code that appears.  I am really confused as to what is going on.  I guess I want to understand each step along the way. Kind of like this.

"""""""""""""""
' to write a record
DIM recordx as info
recordx.PersonsName = "Jane Doe"
recordx.age = 25
recordx.petsname = "Jofers"
"""""""""""""""

I am not sure what this means.
Thanks for bearing with me.  It has been so long since I programmed last.

Thanks
Chris
Logged
casonon
Member
*
Posts: 28


« Reply #6 on: June 05, 2003, 08:19:00 AM »

Maybe someone could email me some programs that use the .dat files in a similar situation as to what I am looking for that way I could see exactly how they are used in a program.  Just and Idea.
If so, email to csonon@ironmount.biz

Thanks all
Logged
Phydaux
Senior Member
**
Posts: 200



« Reply #7 on: June 05, 2003, 10:39:31 AM »

There are basicaly two types of file you can have, sequential and random access.
Sequential files are writtn to and read from in order, from begenning to end (like a tape)
Random access files can be read from and written to at any point (like a CD)

Sequential access files are only really usefull for logs or times when the file isn't going to change often, and be read through from begenning to end.

A Random access file is more usefull for when you want a flatfile database of something. (like a phone book)

A Random access file holds information in RECORDS, a record is a group of information (like name and address) all combined into one.
E.G.
Code:
Phydaux        4 My street                   (029) 20893232
is 1 record containing three strings of lengths 15, 30, 15 respectivly.

This record is a specific DATA TYPE (like an integer, or string) and must be defined.
Code:
TYPE info
   first AS STRING * 15
   street AS STRING * 30
   telephone AS STRING * 15
END TYPE
This defines the data type info. To use these in a variable you need to declare the variable. You cannot use info like a variable, as it would be as silly as saying LET INTEGER = 4.

Code:
DIM person AS info

if you wanted to hold info on more than one person at a time you would just define person as an array.
Code:
DIM person(1 TO 100) AS info



You cannot just write information directly to the person variable (unless the data passed to it is already in the correct format, like reading from a file (but we'll get to that)) but you can write to the different parts like you would a normal variable.
Code:
person.first = "Phydaux"
INPUT "Your street is"; person.street


to save this stuff to a file, you first need to open one. N.B. if the file doesn't exist then it will automaticaly be created.
Code:
OPEN "address.book" FOR RANDOM AS #1 LEN = LEN(person)
this opens up the file "address.book" with RANDOM access, as file number 1, and declares that each record is the length of the person varable.

Now the file is open you can write to it. To write to a file you use the PUT command, where you can specify which file and record to write to, and what to write.
Code:
PUT #1, recnum%, person
This writes all the information stored in person into the recnum% record.
deciding which record to write to is up to you.

To GET information from a file, we use the GET command. It uses exactly the same syntax as the put command.

After we are done with the file make sure to close it or other programs wont be able to access it.
Code:
CLOSE #1
END and SYSTEM also close all open files, but thats a bit lazy and can make it hard to follow a programs layout.

This should be a whole working program randomly accessing the file.
Code:
TYPE info
   first AS STRING * 15
   street AS STRING * 30
   telephone AS STRING * 15
END TYPE

DIM person AS info

OPEN "address.book" FOR RANDOM AS #1 LEN = LEN(person)
   DO
      'this finds how many records there are
      numberOfRecords% = LOF(1) / LEN(person)
      CLS
      PRINT "1) Write info"
      PRINT "2) Read info"
      PRINT "3) Change info"
      PRINT
      PRINT "4) Quit"
      DO
         key$ = INKEY$
      LOOP WHILE VAL(key$) < 1 OR VAL(key$) > 4

      SELECT CASE VAL(key$)
         CASE 1
            'adds information to the file

            INPUT "Name   :", person.first
            INPUT "Street :", person.street
            INPUT "Tel.   :", person.telephone
            PUT #1, numberOfRecords% + 1, person
         CASE 2
            'this will find all the people who share the same first name
            'it can easly be changed to search other parts of the record

            INPUT "Whos information do you want to find"; who$
            FOR record% = 1 TO numberOfRecords%
               GET #1, record%, person
               
               IF RTRIM$(person.first) = who$ THEN
                  PRINT "Name   :"; person.first
                  PRINT "Street :"; person.street
                  PRINT "Tel.   :"; person.telephone
                  PRINT
               END IF
            NEXT record%
            PRINT "press any key to continue..."
            DO: LOOP UNTIL INKEY$ <> ""

         CASE 3
            'this will find all the people who share the same first name
            'and change the information about them

            INPUT "Whos information do you want to change"; who$
            FOR record% = 1 TO numberOfRecords%
               GET #1, record%, person
               IF RTRIM$(person.first) = who$ THEN
                  INPUT "Name   :", person.first
                  INPUT "Street :", person.street
                  INPUT "Tel.   :", person.telephone
                  PUT #1, record%, person
               END IF
            NEXT record%
      END SELECT
   LOOP UNTIL key$ = "4"
CLOSE #1
END
You should obviously refine and talor this to your own needs Smiley HTH
Logged

url=http://www.spreadfirefox.com/?q=affiliates&id=60131&t=79][/url]
END OF LINE.
casonon
Member
*
Posts: 28


« Reply #8 on: June 05, 2003, 12:10:44 PM »

Ok I think I somewhat but not really understand what you are saying.  But here is some code that I entered into my program based off what you told me.  But I get an error when I try and run the program.  The error says "excpected: expression".  No clue what that means. Here is the code.

""""""""""""""""""""""""""""""
   TYPE INFO
      NAME AS STRING * 15
      DATE AS STRING * 10
      PNAME AS STRING *40
      PRNAME AS STRING *30
      PROJECT AS STRING *15
   END TYPE
   DIM LOG AS INFO
   OPEN "C:\PART.LOG" FOR RANDOM AS #1 LEN = (LOG)
   DO
   NUMBEROFPARTS% = LOF(1) / LEN(LOG)
   PUT #1, NUMBEROFPARTS% + 1, LOG
   CLOSE#1
   END
""""""""""""""""""""""""""""""

thanks
Chris
Logged
toonski84
__/--\__
*****
Posts: 2567



« Reply #9 on: June 05, 2003, 12:58:16 PM »

I find the random mode rather... sucky.  I've always preferred binary because it gives you more control.  But that's just me.

it's giving you that error because LOG is a function.  You can't name your variable that.
Logged

i]"I know what you're thinking. Did he fire six shots or only five? Well, to tell you the truth, in all this excitement, I've kinda lost track myself. But being as this is a .44 Magnum ... you've got to ask yourself one question: 'Do I feel lucky?' Well, do ya punk?"[/i] - Dirty Harry
casonon
Member
*
Posts: 28


« Reply #10 on: June 05, 2003, 01:50:09 PM »

toonski.  If yoou can explain your version to me I might like it to.  I would like to have more control.  I just didn't understand your code to well.  
Thanks
Chris
Logged
casonon
Member
*
Posts: 28


« Reply #11 on: June 05, 2003, 01:54:48 PM »

There might be an error because of the LOG but it never gets that far.  I get the error at the AS in the first line of the Type Info.
Logged
Glenn
I hold this place together
*****
Posts: 786



WWW
« Reply #12 on: June 05, 2003, 02:33:01 PM »

the name of another intrinsic QB function.  I changed it to "ANAME" and that part works.  I then changed "LOG" to "LOG1" and changed "LEN = (LOG1) to "LEN = "LEN(LOG1)".  I then got up to the point where LEN(LOG1) was zero and dividing by that is a no-no.  I then got to the point where NUMBEROFPARTS% generated an overflow.  So I changed the "%" to a "&" to make a LONG integer.  (I think the real problem was just that the variable was 0 and PUTting to a 0-position is a no-no.  However, it seems that that variable certainly could possibly exceed 32,767.)  Then I got to the point where there was no "LOOP" statement for the "DO" statement, so I fixed that.  You need to add a termination condition for your loop and actually define some data to output.


TYPE INFO
ANAME AS STRING * 15
DATE AS STRING * 10
PNAME AS STRING * 40
PRNAME AS STRING * 30
PROJECT AS STRING * 15
END TYPE
DIM LOG1 AS INFO
OPEN "C:\PART.LOG" FOR RANDOM AS #1 LEN = LEN(LOG1)
DO
NUMBEROFPARTS& = LOF(1) / LEN(LOG1)
PUT #1, NUMBEROFPARTS& + 1, LOG1
LOOP
CLOSE #1
END
Logged

ravelling Curmudgeon
(geocities sites require copying and pasting URLs.)
I liked spam better when it was something that came in a can.
Windows should be defenestrated.
Phydaux
Senior Member
**
Posts: 200



« Reply #13 on: June 06, 2003, 07:31:00 AM »

Quote from: "toonski84"
I find the random mode rather... sucky.  I've always preferred binary because it gives you more control.  But that's just me.
I just use random mode because I can't see a condition (with what he's trying to do) where binary mode would be of more use.
Logged

url=http://www.spreadfirefox.com/?q=affiliates&id=60131&t=79][/url]
END OF LINE.
casonon
Member
*
Posts: 28


« Reply #14 on: June 06, 2003, 08:26:59 AM »

Ok. Using the methods posted by toonski & phydaux, I arrived at the follwing code.

""""""""""""""""""""""""""""""""
NAME.VERIFY:
LG.DT$ = DATE$
CLS
PRINT "NAME : "; LG.PERNAME$
PRINT
PRINT "DATE : "; LG.DT$
PRINT
PRINT "PART NAME : "; LG.PNAME$
PRINT
PRINT "PROJECT : "; LG.PRJNAME$
PRINT
PRINT "PROJECT TITLE : "; LG.PRONAME$
PRINT
PRINT "IS THIS INFORMATION CORRECT (y/n)"
DO
   KEY$ = INKEY$
   IF KEY$ = "y" OR KEY$ = "Y" THEN
      GOTO WRITE.NEW
   END IF
   IF KEY$ = "n" OR KEY$ = "N" THEN
      GOTO NEW.PART.NUMBER
   END IF
LOOP WHILE KEY$ < "Y" OR KEY$ > "N"


WRITE.NEW:
TYPE INFO
   PERNAME AS STRING * 10
   DT AS STRING * 8
   PNAME AS STRING * 35
   PRJNAME AS STRING * 12
   PRONAME AS STRING * 25
END TYPE

DIM LG AS INFO

OPEN "C:\TEST.DAT" FOR BINARY AS #1
   SEEK #1, LOF(1) + 1
   PUT #1,, LG
CLOSE#1
""""""""""""""""""""""""""""""""""""""""
Now, I get an error when trying to run this that says "Identifer can not contain period."  which I don't understand since you guys have them in your examples.  Please advise what I need to do to fix this.

Thanks
Logged
Pages: [1] 2 3
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!