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!

trying to create a log.txt file 1

Status
Not open for further replies.
Jan 20, 2007
237
US
Hello everyone
i am printing labels and i would like to have a txt file where all the content of each label printed, can be in a txt file by appending to it, each time
i print a label so i can use later the log file to review it and see if i actually did not forget to print labels for a particular sales order details
so here is my code, please see if i used "STRTOFILE() " correct ?
i am not able to find the filename "PrintLblLog.txt", in the path specified, can anyone help me out to straight this out and tell me what is wrong ?
By the way the "LOG" folder exist in the c:\ and i have full access to it
Thanks in advance

Code:
Select sono, Left(Alltrim(Getwordnum(Desc,1)),10) As apexpart, Left(Getwordnum(Desc,2),30)+" "+Left(Getwordnum(Desc,3),30)As Descrip,;
	QTYORD From junkso Where xtick = .T. Into Cursor junkrep READWRITE   && NOFILTER
If _Tally>0 
	Set Printer To Name (_Screen.Printer)
	For lnloop = 1 To Thisform.spinner1.Value    
	  Label Form  label1.lbx Noconsole To Printer
	Next
	Thisform.spinner1.Value = 1
	
	** to create a log text file of labels printed
	LOCAL cFileName,cText
	cFileName = SYS(5)+"LOG"+"\"+"PrintLblLog.txt"
    SELECT junkrep  &&IN 2 ALIAS MYJUNKREP   
    GO top     
  SCAN   &&FOR xtick =.T.   
    cText = sono + "," + apexpart + " "+ ALLTRIM(Descrip) +" "+STR(QTYORD)+ " "+ DTOC(DATE())  + CHR(13) 
    STRTOFILE(m.cText, m.cFileName, 1)
  ENDSCAN && end here 	
Else
	Messagebox("Nothing to print yet!")
Endif
 
STRTOFILE doesn't create directories, the path up to the filename has to preexist.
Check the return value, it tells you the number of bytes written, if that's 0 the file couldn't be created. It won't throw an error, it'll just not write anything.

There are three modes, as almost always:
1. Only specify the file name and write into the current directory.
2. Use a full path as you do, but first check, whether that directory exists.
3. use a relative path and change location of a whole tree of files just with a CD or SET DEFAULT.

I recommend and do work the second way, as it can't be sabotaged from any library using the third strategy, too and not changing the path back. And if you program defensive against such things you get to the point you CD to your default directory again and again, so that strategy only works well, if you have this under full control and only have the one working directory for your whole application. In some way a default directory is a simplification to easily have that movable even just in the working directory of a lnk file starting the application, but in a way to me it's always quite as unfortunate as a public variable, even worse, as you could have your own name and not let other code change that value, any code CDing somewhere else can destroy the behavior of your code.

I usually have the root path in a class property read in from a config INI or DBF and upon init the path (JUSTPATH) is checked for existence (DIRECTORY()-Function) and generated (MD), if missing. This can be a base class' code you reuse for logging or any other file output, so this is really a base functionality for most anything in a file-oriented database application. You might like a base function library instead, whatever, but handle base stuff once and for all and reuse that and you don't stumble upon such things.

Also, while we're at it, you may, for now, dislike STRTOFILE failing silently without throwing an error, but get used to not always be informed about any mischief from VFP commands, just as SQL Passthrough, just aa ERASE also doesn't error, if it either doesn't find a file to erase or doesn'Ät get the necessary access to erase it. Used the right way this can be used cleverly.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Hi Olaf, i got it, i was able to fix it.
i was missing the below
cFileName = Sys(5)+"\"+"LOG"+"\"+"PrintLblLog.txt"

what i would like, is to include in the txt file as the first row, the field names that belongs to the cursor junkrep
so i can have in the txt file like
sono apexpart Descrip QTYORD and below then the values, so far i have the values
it is possible to have the fields name as above included in the txt file ?
Thanks a lot
 
Hi everyone,
i just created a fix folder and file where the data will be written, the little problem i have is, as this is txt file, by default the when the user will open the file 'printlbllog.txt' as i said it opens with 'Notepad'. of course we can open with word and will be in better shape but i am wondering if
i can make in still look beeter in Notepad, if anyone can indicate will be good.

1- the path is cfilename = Addbs(sys(5))+'log\printlbllog.txt'
2- when i open the file, the first row which i included are the headers*in this case the field names form the cursor, some of them does not align correctly more and less with the below rows(in this case the values)
here is the code for appending to the filename

Code:
** to create a log text file of labels printed
	Local cFileName,cText	
	cfilename = Addbs(sys(5))+'log\printlbllog.txt'	
	Select junkrep  
	Go Top	
	cText= 'SONO  APEXPART   DESCRIPTION           QTY        DATE     '+ CHR(13)
	Strtofile(m.cText, m.cFileName, 1)
	Scan   
		cText = ALLTRIM(sono) + "," + apexpart + " "+ Alltrim(Descrip) +" "+Str(QTYORD)+ " "+ Dtoc(Date())  + Chr(13) ct
		Strtofile(m.cText, m.cFileName, 1)
	Endscan

please my txt file and advise if possible, what can i do to align a little better headers and values, i realized also that the headers
will be added each time i run labels again as
cText= 'SONO APEXPART DESCRIPTION QTY DATE '+ CHR(13) is there

Thanks as always.
 
 https://files.engineering.com/getfile.aspx?folder=c66d503d-c6ab-4e9d-871f-145292a0f5d4&file=printlbllog.txt
The only way to align the headers is to use a fixed-pitch font, such as Courier New. That's not something you can speify from within VFP. It is a function of the program which you are using to display the file.

The text editor which I use (Notepad++) always uses a fixed-pitch font. With Notepad, you can choose the font. As you can with the built-in VFP text editor.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
The default for Notepad also is Courier New. You must have changed it.

And yes, I second Mike in that you don't have control about the program associated with TXT. You could name the log with .log extensions, then normally no program is associated.
Anyway, even if you name it .dbf in theory the file extension can be associated with anything else and so you only have control about the look of any ASCII text file if you display it, eg in an Editobx where you can set the font and font size as you want.

Anyway, you should not care, as any sensible user able to get something from a log file will be able to know his text editor enough to set the font, eg in notepad (German):
notepad_font_dzhc4c.jpg

notepad_font2_dgh7tj.jpg


The question really is, whether the end user of your logfile someone else but you yourself? If so, is he really not computer savvy at all? Then you could write out something that formats itself, like RTF, doc(x), HTML. In theory, even HTML files could open as the HTML source code in notepad or an HTML editor, if the user does web development, but for such a user normal associations can be assumed. For the same reason you could assume his notepad is at default Courier New font and you don't have a problem. But I assume the problem arose for you already, or you wouldn't have that question.

Maybe that user once asked someone whether the font in notepad can't be set to something prettier, and there you have the salad (is an idiom we'd say here). In the end, you're never fully controlling everything, HTML would be fine, but has a simple problem, even if you start writing out an HTML head with CSS definitions for the look up to a <body> opening tag minus the final closing </body></html> tag. Without these end tags, the HTML isn't complete and could render okay in quirks mode, but you'd want to write it out so the new text would not be added at file end but before the closing </body> and </html> tags. STRTOFILE() as your log file extension tool doesn't offer that, so you'd need to work on the file with FOPEN, FSEEK, FWRITE, FCLOSE. RTF has the same problem and is even worse to write "by hand" or with the RTF tags, HTML is friendlier.

Anyway, you can have tab alignment and such things in Word documents. Log files by definition are raw files and the reader of a log file shouldn't need something pretty formatted at all. That's the wrong expectation from log files. If you align things with the number of characters you have to instruct the user of the log files to read it in a monospaced font, that's all and that's the usual way to set your ASCII text editor for exactly that reason. Log files don't have any fancy by pixel alignment and colors and graphics.

Even if you knew all the pixel widths of characters in a specific proportional font, you rarely have a character exactly 1 pixel wide you could use to align anything else. Spaces will normally be 2-3 pixels wide at least and so proportional fonts are only aligning well in a word processing software supporting real tabs as a certain pixel offset position where the new text begins and is perfectly aligned. Or HTML with tables or CSS alignments of flex-grid or other modern HTML concepts.

I don't assume you want to go anywhere as complex as that is and so just set your notepad configuration back to normal Courier New and you'll be fine. There's no way to have that per file, this is a notepad setting, not a file property.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Another approach would be not to open the file in an external editor, but to create a VFP form for the purpose.

Create a form, and drop an EditBox control on it. Make the control fill the form. In the form's Init, use FILETOSTR() to get the contents of the log file into a variable, and then place that in the Value property of the EditBox.

Set the EditBox's FontName to, say, "Courier New".

Do you want to prevent the user from editing the log file? If so, simply set the EditBox's ReadOnly to .T. (and probably change its ForeColor and BackColor to make it more easily readable).

(If you open the file in a text editor such as Notepad, you can make the file read-only, but you can't prevent the user from editing it; you can only prevent them from saving it.)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I suggested an Editobx, darn typos. But you're right, Mike. That'd be another way to keep this under your control. Anyway, a double click on a TXT file wouldn't open VFP, so you'd have a log file viewer as feature of your own software and to only let users use that feature, don't give log files a TXT extension, maybe even no file extension at all, a rarely used feature, but also doable to have no association with any software whatsoever of such files.

You can also create an association with your own software, but that needs some serious implementation of Win API features and isn't done in a few lines, see
Bye, Olaf.

Olaf Doschke Software Engineering
 
Guys.
Great explanation and good clues from both, thanks alot
Mike i like the idea of the EditBox control, so one thing i don't know is, if this will always have in the EditBox all the records that have been previously printed ?

or perhaps i can append from the cursor "junkrep" into a table, then later allow them from a cmdbutton to open a grid to show there the records from that table, the issue with it, will be that then one user will see records from another user, unless i create a login form and then record a username so when they open the form, then depending of the user, the grid will show only reoords based on that username.
sorry, maybe i am making this a big deal

Thanks
 
Well, you're responsible for who can see which data, that can't be prevented with file extensions or not, so in the first place you'd write files out to a private directory of a user only that user can access. That's valid for both TXT logfiles and DBFs.

Aside of that the idea with an editbox is to load the full log TXT file into its value with the opposite function for creating TXT files FILETOSTR() instead of STRTOFILE() will simply read in a full file.

As a side note, log files are typically logging errors happening or other info. What you do here is outputting data formatted, a TXT file report. If you want to print that and see that as printed use FILETOSTR. But as you're generating the TXT from data you already have in memory and at hand, of course, you can display that data in a grid and, of course, that easily means having the columns align as grid columns, you can even have the ability of right-aligning numbers and left aligned text. And you don't need to fiddle with whitespaces for that matter.

If you're really not knowing what you have at hand as features of VFP, please consider buying one or two Hentzenwerke books or watch some tutorial videos you find about VFP, just google VFP videos and switch to video results and you find many things at Youtube. There's more than ever and Garfield Hudson isn't the only one providing them.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Ernesto, as Olaf says, the contents of the log file is completely under your control. Once the data is in a variable, you can use VFP's extensive string-handling to extract and show whatever data you like. That's the advantage of doing the whole thing in VFP rather than going out to Notepad or whatever.

Your idea of using a grid is worth following up. That's what I've done in similar cases. You could even do away with the log file, and store the data in memo fields in a log table. The table could also have fields for date, user, etc. The user would be able to select the record of interest - for example, for a particular date - and you would then display the log data from the memo field.

Regarding one user not seeing another's data, you don't need to go as far as setting up a login form (although there might be other reasons for doing that). You could identify a user simply by checking SYS(0) - although that assumes that each user has his own computer and/or his own Windows login.

Lots of possible approaches to consider.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike , i was not very aware of FILETOSTR() use, that is why i got confused, but either way as you said can be done and in fact the idea of notepad it is not good as actually there is not control of the format, so will experiment with FILETOSTR() or Dbf
Thanks again
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top