|
Hi,
I missed the fact the file could preexist. And yes my code increments the lines generated, however it starts at 1.
if you need to append to an existing file, you have to figure the number of lines present; there are two rather safe ways to do that:
1. read through the entire file, line by line, and count them.
2. read through the entire file, keep the last line, isolate the line number and parse it.
Other ways would include:
3. keep a copy of the last line number somewhere (in registry, in another file, ...)
4. not to use line numbers, use something else than increases all the time (but not by 1), example:
the number yyyyMMddHHmmss containing numeric parts of date and time.
Whatever you do with files, chances are it will fail if and when your app is running more than once at a time on a single computer. And also when it runs on several machines.
The solution, if relevant, is to use a database, where each app would add records to a table, with one of the fields made a primary key, unique and auto-incrementing.
|
|
|
|
|
You have to append a text-line (that includes for each line an incremental number) to a pre-existing file, not to append a line number to a text file!
Is it correct?
Do you need to add a new line to the file, each time you input a new line, or before you want to input several lines and then to append them at the end of work?
How many lines do you preview to write in the log file (maximum), and how many characters have each line (maximum)?
modified on Thursday, September 10, 2009 2:30 PM
|
|
|
|
|
Hi Hurricane3000,
Thanks for the input, I'm so confused probably why it's taking me months to try to resolve this problem.
I have already managed to get the text file made and written to from my text box. Each time an entry will goto a newline.
For example :the log file is created on first entry if it does not exist...
A report of one line is submitted from my textbox to the text file and is added to and a new file will be created monthly.
Each entry in my text box is submitted one at a time into the same text file but on a new line.
Every entry is written to a newline I have got this part working.
The form is shared between 2 technicians reporting various faults but writing to the same file within a network, I have got this part working too, without any issues or access problems.
My issue is I would like to add line numbers as the file is written to for each logged entry
I'm grateful for any assistance in resolving this battle, my vb is limited but I some how manage.
regards
CJ
|
|
|
|
|
You not answered to my questions yet ,
You have to append a text-line (that includes for each line an incremental number) to a pre-existing file, not to append a line number to a text file!
Is it correct?
Do you need to add a new line to the file, each time you input a new line, or before you want to input several lines and then to append them at the end of work?
How many lines do you preview to write in the log file (maximum), and how many characters have each line (maximum)?
Can you send me a sample of a text-line that you need to append?
|
|
|
|
|
HI Hurricane3000,
Perhaps I mean to add an inc remental number as the lines are sent to the text file so that the line numbers are counted and added to as the file grows.
There is no limit to the max characters typed per line but usually is just a brief explanation of the issue
here's what I have so far:
' This text is always added, making the file longer over time
sw = IO.File.AppendText(path)
sw.WriteLine(DateTime.Now.ToString() + "," + "Reason," + (RichTextBox2.Text)
so where I'm using writeline i would need it to add a incremental line number first, so if the log already had two entries it would need to put a number 3 before datetime.now, so I think it would somehow have to count any existing lines in my text file.
My text file at present is as follows:
IT Report Log File Started,10/09/2009 02:03:53
**********************************************
10/09/2009 18:32:27,Reason,test,Approx Time,Duration
10/09/2009 18:32:33,Reason,pc would not power on,Approx Time,Duration
So as each line is made I would like it to be numbered before the date entry.
to continue as follows:
IT Report Log File Started,10/09/2009 02:03:53
**********************************************
1. 10/09/2009 18:32:27,Reason,test,Approx Time,Duration
2. 10/09/2009 18:32:33,Reason,pc would not power on,Approx Time,Duration
Then when a new entry is submitted from my textbox it will write line number 3 and so on
If this doesn't help I could sent you my project
Regards
CJ
modified on Thursday, September 10, 2009 4:26 PM
|
|
|
|
|
1)How many lines will contains the file?
2)Normally, how many lines do you want to add (in the file) at same time? 1 or more than 1?
|
|
|
|
|
Hi Hurricane3000,
1. The file can contain upto 200 or 300 lines max dependant on issues reported that month
2. Only 1 line at a time will be added to the file
The file will take about a month too reach 300 lines some files only reach 160 or so.
regards
CJ
|
|
|
|
|
Hi,
Assuming that your problem is ONLY that to add a progressive number for each new line added in the file,your problem is more easy to resolve than you think.
You simply must go in the optical vision of what you want obtain(you have not much fantasy)!
Like already told you by Luc Pattyn, there are several way to obtain that you want.
For your case I suggest you this:
1) You have to read the entire file and count the lines in it contained.
Following code can do this work. At the end, CountLines will contains the number of lines already contained in the file.
Note: If the head of file will contains not numbered lines, you'll have to subtract them from CountLines.
Using sr As StreamReader = New StreamReader(myStream) 'mystream = Path of File
Dim line As String
Dim CountLines As Integer = 0
Do
line = sr.ReadLine()
If line = Nothing Then Exit Do
CountLines = CountLines + 1
Loop Until line Is Nothing
sr.Close()
CountLines = CountLines - 4 'The number 4 indicate eventually first lines to subtract.
End Using
2) To append a new line in the file, you simply have to change your code-line:
sw.WriteLine(DateTime.Now.ToString() + "," + "Reason," + (RichTextBox2.Text) to
CountLines = CountLines + 1
sw.WriteLine(CountLines.ToString + " , " + DateTime.Now.ToString() + "," + "Reason," + (RichTextBox2.Text) Note that code I sent you, close the file after read it. Then you have to re-open it.
And also note that the code will have no effect on lines already written, but only on newest.
May be that you'll need to modify the "scope-visibility" of CountLines.
Hope this help you
Ignazio
modified on Friday, September 11, 2009 3:42 PM
|
|
|
|
|
Hi Ignazio,
Many, many thanks for the brain refresh. I had grown tired took the weekend of to refresh.
Well thank sfor the code and a few mods and it works swell, here's what I have now and it probably could be shorter than what I have but I'm still learning. See what you think:
Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click
If ComboBox1.SelectedItem = "" Then
Me.Hide()
Dialog1.ShowDialog()
Return
Else
End If
Dim fso
Dim fol As String
fol = "\\Sv1\technician\IT report"
fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(fol) Then
fso.CreateFolder(fol)
MsgBox(" Folder created", MsgBoxStyle.OkOnly, "Folder Created")
Else
MsgBox(" Log File Updated", MsgBoxStyle.OkOnly, "Log Updated")
End If
Dim path As String = "\\Sv1\technician\IT report\IT Report Log.txt"
Dim sw As IO.StreamWriter
If IO.File.Exists(path) = False Then
sw = IO.File.CreateText(path)
sw.WriteLine(Date.Now.ToString() + "," + ("IT Report Log File Started"))
sw.Flush()
sw.Close()
IO.File.SetCreationTime(path, Date.Now())
End If
Using sv As IO.StreamReader = New IO.StreamReader(path)
Dim CountLines As Integer = 0
Dim line As String
Do
line = sv.ReadLine()
If line = Nothing Then Exit Do
CountLines = CountLines + 1
Loop Until line Is Nothing
sv.Close()
CountLines = CountLines - 1 'The number 1 indicate eventually first lines to subtract.
sw = IO.File.AppendText(path)
CountLines = CountLines + 1
sw.WriteLine(CountLines.ToString + ". " + DateTime.Now.ToString() + " " + (ComboBox1.Text) + "," + (TextBox1.Text) + "," + (ComboBox2.Text) + "," + "Reported by," + (ComboBox3.Text) + "," + (DateTimePicker1.Text))
End Using
sw.Flush()
sw.Close()
Dim sr As IO.StreamReader = IO.File.OpenText(path)
Dim s As String
Do While sr.Peek() >= 0
s = sr.ReadLine()
Console.WriteLine(s)
Loop
ComboBox1.SelectedIndex = -1
ComboBox2.SelectedIndex = -1
ComboBox3.SelectedIndex = -1
TextBox1.Text = ""
TextBox2.Text = ""
TextBox3.Text = ""
sr.Close()
End Sub
Once again thanks to all that help with this one.
Best regards
CJ
|
|
|
|
|
I need to communicate from one computer to another, on a network, when an event is detected. I can do it now by writing to a file and then, using a timer interupt, check it often, but I lose valuable time. Thanks in advance for any insight. I program, but am not a "programmer". bill
|
|
|
|
|
You can set a file watcher so an event fires when the file gets changed. That seems the easiest way forward from what you have.
http://msdn.microsoft.com/en-us/library/28y7bbdc(VS.71).aspx[^]
Christian Graus
Driven to the arms of OSX by Vista.
Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.
|
|
|
|
|
Good day,
I know there are numerous questions about the HRESULT 0x80040154 (REGDB_E_CLASSNOTREG) error, and I have seen all (maybe most) of the solutions, but none of those are of any help, I donwloaded all the possible apps that have been suggested but none of those work.
I am using Visual Basic 2005, XP and Office 2003 ( I prefer to use this combination), I am also using the following dll's:
- Interop.Word
- Interop.Excel
- Interop.Outlook
- MySql.Data
- All default dll's
The program I have designed works perfect on my computer, but when I install it on another pc, I get this error. The other pc's have .net framework 2.0 on them, which is required for the installer to work.
Ok, now where the error occurs - I am only giving two places of occurence, but it occurs throughout the program:
A)
As an example, there are two forms, frmMain and frmSecond, and frmMain has a button with the following code :
<br />
frmSecond.Enabled = true<br />
frmSecond.Visible = true<br />
When I click the button, the error occurs at the first instance where the form object is referenced, in this case, it will be at
frmSecond.Enabled = true ,
if this line is commented out will occur at
frmSecond.Visible = true , etc.
At first I thought it is because of my global variables being created as other forms or classes, so I made those local variables, local to the method using them, but that wasn't the case.
B)
As another example, there is one form, frmMain, and a class, clsSomeClass, and frmMain has a button with the following code :
<br />
dim clsSomeClassRef as new clsSomeClassRef<br />
clsSomeClassRef.method(parameter(s))<br />
for simplicity, the clsSomeClass manipulates a SQL database, for this example, lets say it creates as new entry in the database.
When the button is clicked, the error will pop up at
clsSomeClassRef.method(parameter(s)) ,
and the class only has the MySql.data dll.
I am at a complete loss of reasons, my first thought of why this is happening, is because VB is platform dependent, so I have to/must redo the program in C#, which is not platform dependent, but I first want to make sure that C# won't produce the same error, as it is a lot of work and code to redo.
I you guys could help me with this error, I would be highly grateful and thankful and your efforts would be much appreciated!!
It is kinda urgent,
Thanks a lot,
Rossouw
|
|
|
|
|
Member 4247277 wrote: my first thought of why this is happening, is because VB is platform dependent, so I have to/must redo the program in C#, which is not platform dependent, but I first want to make sure that C# won't produce the same error, as it is a lot of work and code to redo.
This is absolute rubbish. VB and C# produce code in the same MSIL, for the .NET framework
Member 4247277 wrote: I am using Visual Basic 2005, XP and Office 2003 ( I prefer to use this combination), I am also using the following dll's:
- Interop.Word
- Interop.Excel
- Interop.Outlook
- MySql.Data
- All default dll's
Is office installed on the computers you're using ? Because the error you're getting, means that COM dll is not registered. The solution to this is to run RegSvr32.exe on the dll in question, if you distribute a COM dll. None of these are COM dlls, that I can see. Office DOES use COM, the interop dlls could well be for COM interop, and they could be complaining that the actual COM dlls they want to work with, are not present.
You can use .NET instead of COM to work with Office, using the Microsoft Tools for Office. However, your app in either instance, will only work if Office is installed on the target PC.
Christian Graus
Driven to the arms of OSX by Vista.
Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.
|
|
|
|
|
Hi Christian,
Thanx for clearing up the platform independent stuff, I have been using VB for quite some time, and people critisize me for sticking with vb, but vb is quite a powerful language though.
The pcs have office installed on them, I will give the RegSvr32 a try, I didn't bother to look at it, as I have read that if you are using an installer, it will automatically register the dlls. Is there any other way (other than using COM, which I will have to register) to use Excel, Word and Outlook, or are including them in my project the only way?
Thanks again, you have saved me a lot of work!
|
|
|
|
|
Member 4247277 wrote: and people critisize me for sticking with vb, but vb is quite a powerful language though.
VB6 was crap. VB.NET and C# are largely interchangable. People assume that b/c C++ was better than VB6, C# is better than VB.NET and it's not true.
Member 4247277 wrote: I didn't bother to look at it, as I have read that if you are using an installer, it will automatically register the dlls.
You don't have any dlls that need registering, at least, not in the list you provided. I don't think so, anyhow. My next step would be to look at the event code in the form that blows up when made visible, and add message boxes to work out which call is causing the error. It will be code that uses one of these libraries. Once you know which library has an unregistered dll, you'll have a much better starting point.
Member 4247277 wrote: Is there any other way (other than using COM, which I will have to register) to use Excel, Word and Outlook, or are including them in my project the only way?
You can use the Microsoft Tools for Office, which with newer versions of office, connect directly through .NET without COM. But, if Office works on these PCs, the dlls are registered. Your interop dlls define the connection to come, they don't need registering.
Christian Graus
Driven to the arms of OSX by Vista.
Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.
|
|
|
|
|
Thanks Cristian,
I have used messageboxes, thats how I came up with the questions providing where the errors occur.
The biggest problem that I have is this - I will guide you through what I did, so that you can see what has already been done.
<br />
'Global variables<br />
Private cls1Ref as New clsClassOne<br />
Private cls2Ref as New clsClassTwo<br />
Private cls3Ref as New clsclassThree<br />
Say, that clsClassOne is used to manipulate - add, edit, remove, get, etc - data from a SQL database, table name : tableOne; clsClassTwo is used to get data from a SQL database, table name : tableTwo; and clsClassThree sends email, creates new Word documents and makes graphs in a Excel sheet, all using the same database.
Now, if these global variables are the global variables of my main form, the form won't load, the class not registered error message is displayed; if I now make the global variables local to the methos that will use the variables, say I have three buttons, each with its own class reference :
<br />
'No Global variables<br />
'Only for the main form<br />
Private Sub Button1_Click(.....)<br />
dim cls1Ref as New clsClassOne<br />
cls1Ref.add(........)<br />
End Sub<br />
<br />
Private Sub Button2_Click(....)<br />
messageBox("Before Ref")<br />
dim cls2Ref as New clsClassTwo<br />
messageBox("After Ref")<br />
dim name as String = cls2Ref.get(.....) 'If the retrieved value is to be a string<br />
messageBox("After Retrieval")<br />
End Sub<br />
<br />
Private Sub Button3_Click(....)<br />
dim cls3Ref as New clsClassThree<br />
cls3Ref.sendMail(.......)<br />
End Sub<br />
OK, now, this is an example after I have made the global variables local, and added messageBoxes to catch where the error occurs.
Now, if this is to be in the main form, the main form will load successfully, if either button 1 or button 3 is clicked, the class not registered error will occur, but if button 2 is clicked, messageBox("Before Ref") will pop up, then messageBox("After Ref") will pop up, and then the program will crash, no error, nothing, so the obvious problem then lies at cls2Ref.get(.....).
Because of this, I now have made all the global variables that are assigned classes local, so now we use the same buttons with the same code, and the same thing happens as if the variables have stayed the same.
All classes and forms use any combination of the following dlls :
-Interop.Word
-Interop.Excel
-Interop.Outlook
-MySql.data
Some don't use the MySql.data at all, some uses only the MySql.data, and other don't use any at all.
At this current moment, all my global variables that are classes are local (as explained above)
The connection to my database works fine, as in my main form a username and password is typed in, which is validated right there on the spot, no seperate class is used for this, also, excel reports are being printed and emails are sent from the main form (only these that aren't accessed via a seperate class).
I really hope my explanation is sufficient and clear and that you have a good idea of what is happening.
I appreciate all your efforts a lot,
Rossouw
BTW : Your blog is excellent!!
|
|
|
|
|
I have tried to register my dll's, but I get the following message:
dll was loaded, but the DllRegisterServer entry point was not found.
This file can not be registered.
|
|
|
|
|
Still an issue with UserControls here, with inconsistent behavior of SuspendLayout and ResumeLayout .
My UserControl consists of 3 panels and 2 buttons .
Docking and anchoring is used to mimic consistent 'look and feel' despite the size of the control (primarily Width ).
A Menu Control is populated with numerous instances of the UserControl defined above. Using a loop, I am resizing all these controls to an appropriate Width which is dynamically generated.
To increase performance as well as usability, my intention was to call SuspendLayout, resize the control by increasing or decreasing the Width, then calling ResumeLayout(True) so that a user does not see redrawing on the screen.
Obviously, without SuspendLayout() and ResumeLayout(True) the user will see the controls redrawing, which is time consuming and very poor to see.
However, when SuspendLayout() is called and then the control's Width property is changed, after ResumeLayout(True), the control is never resized. The Width property shows that the control's Width should be what I set, but the control is visibly unchanged.
What's worse is this behavior is not duplicated on another UserControl which has a similar hierarchy of panels and buttons, using the exact same loop those controls resize visibly as intended.
On a side note, I have enabled Double Buffering on all controls for faster drawing, albeit with little to no visible effect on the resizing of these controls.
My secondary solution involved shadowing SuspendLayout() and ResumeLayout() to loop through all controls and force SuspendLayout on the controls children, but that proved problematic and the lack of hits on Google and MSDN on either shadowing or overloading / overriding the SuspendLayout and ResumeLayout methods proved ineffective.
If any of this is unclear, it is because I have not had to much coffee today, so I'll answer any unclear statements about my problem at hand.
Example coding:
Dim o As System.Windows.Forms.Control
Me.ControlMenuComboBox.Width = i
For Each o In _collection
o.SuspendLayout()
o.Width = i
o.ResumeLayout(True)
o.Update()
Next ' the controls in the above loop DO NOT resize visibly as intended, Width property shows value of variable i.
For Each o In Me.Controls
o.SuspendLayout()
o.Width = i
o.ResumeLayout()
Next ' the controls in the above loop resize visibly as intended, Width property shows value of variable i.
As I assume the following is important I cannot stress it enough; all controls show the Width property has been set to variable i, however I feel that SuspendLayout() is inconsistent between my UserControls.
|
|
|
|
|
Hi all,
I encountered a little problem, after I decided to tramsform a Sub in a Function (and made the name of the array involved in Function, as argument to pass to the Function as string).
Code (Note: Asterisks and Number Sign # are note part of code)---------
Public Function ReadField(ByVal NameArray As String, ByVal Field As Integer) As String
'Dim NameArray As String
# Dim LenString As UInteger = Len(NameArray(ComboBox1.SelectedIndex + 1))
StringWpt = "" : Index = 0 : CommaCounter = 0
Do Until CommaCounter = Field - 1
* If NameArray(ComboBox1.SelectedIndex + 1)(Index) = "," Then CommaCounter = CommaCounter + 1
Index = Index + 1
Loop
* If Index = Len(NameArray(ComboBox1.SelectedIndex + 1)) Then GoTo 10
Do Until NameArray(ComboBox1.SelectedIndex + 1)(Index) = ","
* StringWpt = StringWpt + NameArray(ComboBox1.SelectedIndex + 1)(Index)
Index = Index + 1 : If Index = LenString Then Exit Do
Loop
10: Return LTrim(StringWpt)
End Function
Logically, the code (when working as Sub) is correct and works fine .
The problem is that exactely like is written above, the Function generate 3 errors "Expression is not an array or a method, and cannot have an argument list" in the lines I signed with *, but strangely is not generated in the line I signed with #.
If I enable as code the comment-line immediately below the definition of Function, and re-define again NameArray, the 3 errors are substituted with a single Error: "'NameArray' is already declared as a parameter of this method".
Note: When working as Sub, I not used the Array-name as variable, but I used the effective name of Array.
Do I forgotten something or is not possible to pass an Array name as argument?
Thanks for help
Ignazio
modified on Wednesday, September 9, 2009 12:16 PM
|
|
|
|
|
You cannot use the contents of a String variable as a variable name.
I'd suggest rewriting the entire concept using collections of arrays, but, given the code sample you posted, I'm not sure if my explanation is going to make any sense to you at all. You're using VERY old BASIC concepts in VB.NET. I would HIGHLY suggest picking up a beginners book on VB.NET before continuing this project.
|
|
|
|
|
Thanks for reply Dave,
But I can accept only first part of your help.
For second part, I let you know that I decided to not use a collection of Arrays because rarely I need to use more than 1 Array and I found this solution the more convenient(and efficent)for me.
I understand what you want say, but I not agree with you when you write that latest concepts of VB.NET are better than older concepts of Basic.
Often old concepts of Basic are better and more efficent than latest.
It's not a case that Microsoft mantained the compatibility of "Old Basic" in VB.NET
And it's for these reasons that when possible (and convenient)I prefer to use the "OLD concepts".
I not uderstand where in the code you see something that remember to you "Very old concept of Basic".
If you refer to the GoTo instruction, do you really think that changing it the code is improved (or made more efficent)?
Ignazio
|
|
|
|
|
Hurricane3000 wrote: but I not agree with you when you write that latest concepts of VB.NET are better than older concepts of Basic.
Often old concepts of Basic are better and more efficent than latest.
Well, you should ponder this:
1 - A Microsoft team worked to clean up and improve VB, do you think you know better than them ?
2 - In fact MS wanted to stop VB users from being able to use old VB6 concepts completely, because they are that bad, however, a bunch of luddite MVPs howled about it and so they changed it at the last minute.
Christian Graus
Driven to the arms of OSX by Vista.
Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.
|
|
|
|
|
Hurricane3000 wrote: but I not agree with you when you write that latest concepts of VB.NET are better than older concepts of Basic.
Considering your having problems with code written in the Dark Ages and could be far better resolved with modern OOP code, I think you're wrong.
You've got legacy concepts all over that code snippet you posted. From the colons to the Goto to the non-terminated If statements and then some, you've got legacy concepts written all over this.
I haven't used a Goto statement in, let's see..., oh! 9 years now.
The more you use the old concepts, the deeper the hole you're digging yourself. If you want to maintain an ancient relic of a skill set, go ahead. You're only limiting your own abilities to keep a job.
|
|
|
|
|
You are passing a string as a parameter. It will not behave as an array. You will need to pass the array as a method parameter. I would second Dave's recommendation to getting a book.
It's not necessary to be so stupid, either, but people manage it. - Christian Graus, 2009 AD
|
|
|
|
|
Thanks for help,
I think I'will follow your guideline.
But I don't think will be necessary to buy and read a book.
Ignazio
modified on Wednesday, September 9, 2009 3:40 PM
|
|
|
|
|