Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Sleep is good. Coffee is better.

Let's say your audit table looks like

UserName    DateIn                 DateOut
--------    -------------------    -------------------
Jim         2012-03-27 11:30:23    2012-03-27 11:45:19
Jim         2012-03-29 08:15:12

And the current date is today. The reason that record two has no value for DateOut could be one of

  • The network failed
  • The server died
  • The user kicked out the power cord on his computer

Or several other reasons. In any case, when Jim goes to log back in he will end up with the following

UserName    DateIn                 DateOut
--------    -------------------    -------------------
Jim         2012-03-27 11:30:23    2012-03-27 11:45:19
Jim         2012-03-29 08:15:12
Jim         2012-04-01 13:24:17

This is not good because it looks like Jim has logged in twice without logging out. Come to think of it, if it is possible for a user to log in on two different machines at the same time then you might add a machine name field to the audit table (a good idea in any case). Let's keep it simple for now. When the app starts you will have to check for unclosed logins and put some value in to "close" them. Let's assume that has been done and the audit table now looks like

UserName    DateIn                 DateOut
--------    -------------------    -------------------
Jim         2012-03-27 11:30:23    2012-03-27 11:45:19
Jim         2012-03-29 08:15:12    2012-03-29 24:00:00
Jim         2012-04-01 13:24:17

If you were to use the query

UPDATE AuditTrail SET DateTimeOut = now() where Username ='Jim'

You would end up with

UserName    DateIn                 DateOut
--------    -------------------    -------------------
Jim         2012-03-27 …
poojavb commented: very nice explained.... +3
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

If you are just saving it into the database then you don't need datasets and datatables. But I suggest you use a datetime field instead of separate date and time. To add the login record you can do

Dim con As New ADODB.Connection
con.Open("Driver={SQL Server};Server=.\SQLEXPRESS;Database=mydb;Trusted_Connection=yes;")

Dim query as String = "insert into AuditTrail (UserName,LevelOfAccess,DateIn,TimeIn) "
                    & "  Values(" & Quote(TextBox1.Text)      & "," 
                    &               Quote(LevelOfAccess.Text) & ","
                    &               Quote(Now())              & ")"

con.Execute(query)
con.Close

Private Function Quote( field As String) As String
    Return "'" & field & "'"
End Function

The query to update the audit trail when the user logs out is

Dim query as String = "update test1 set DateOut=getdate() where DateIn="
                    & "  (select MAX(DateIn) from Test1 where UserName = '" & username & "')"

Keep in mind that you may need cleanup code to resolve records where a DateOut is not inserted due to program, machine or network failure.

Begginnerdev commented: Nice formatting. +4
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Or you could use a SortedList and not have to do the sort yourself.

Dim mylist As New SortedList

mylist.Add("John", 23)
mylist.Add("Jim", 14)
mylist.Add("Fred", 92)

For Each key As String In mylist.Keys
    Debug.WriteLine(key & ": " & mylist(key))
Next
Begginnerdev commented: Nice, I didn't even think of SortedList +0
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Here is a question I do not recall being addressed. In the last week I have had to completely rebuild my system. Following a lengthy install and configuration I had to look for the locatiuon of a settings file for an application (to make a backup). Being a dinosaur, I prefer to do this from the command line so I did the following

C:\>cd \users\jim\appdata
C:\Users\Jim\AppData>dir *inspiron* /s

In a very short time I started getting multiple lines of

The directory name C:\Users\Jim\AppData\Local\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Microsoft\Internet Explorer\Recovery\Last Active is too long.

Upon further checking I discovered that I seemed to have a recursive directory. I suspect that one of the entries was pointing back on itself so that the directory tree was effectively infinite. The problem is in the AppData\Local folder. A listing of the entries at this level shows

 Directory of C:\Users\Jim\AppData\Local

2012-03-30  12:35    <DIR>          .
2012-03-30  12:35    <DIR>          ..
2012-03-27  22:01    <DIR>          {050CAF75-5613-460F-BA72-014A6E41ACF6}
2012-03-28  13:02    <DIR>          {1D0110D3-61AD-4D4F-A99F-77B21023807E}
2012-03-30  06:30    <DIR>          {2B8150D2-D4BB-43CA-979B-760BA277B825}
2012-03-29  05:49    <DIR>          {308C1C85-C323-4423-A3E7-11FD2A9997B9}
2012-03-28  10:01    <DIR>          {50C9FA41-8D3F-4B92-8BB0-713B045ED48F}
2012-03-27  10:00    <DIR>          {70050B67-D3DF-4D7A-A3DA-3315A1905FF3}
2012-03-28  13:47    <DIR>          {A43BF7CD-1BE4-4B77-90F5-CA9586D76BFF}
2012-03-29  17:50    <DIR>          {C5E780B7-A294-4753-973F-3F653C6C6F24}
2012-03-30  06:30    <DIR>          {CAC314B1-F3B7-416E-BEFF-AC6C9370BFE4}
2012-03-28  13:51    <DIR>          {F2AB3D3B-CF02-4570-BF2E-B56800962B12}
2012-03-27  17:00    <DIR>          ACD Systems
2012-03-27  18:47    <DIR>          Adobe
2012-03-26  23:21    <DIR>          assembly
2012-03-26  23:11    <DIR>          DDMSettings
2012-03-28  08:34    <DIR>          Diagnostics
2012-03-26  23:18    <DIR>          Downloaded Installations
2012-03-26  22:33    <DIR>          http___www.fosoft.net_
2012-03-30  08:40    <DIR>          Microsoft
2012-03-27  21:53    <DIR>          Microsoft Games
2012-03-28  13:11    <DIR>          Microsoft Help
2012-03-27  15:45    <DIR> …
Begginnerdev commented: Repeating Application data made me laugh +4
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Naturally, I don't notice the typo until just after I commit the post. With the old system, I was able to click "Edit" to immediately correct the typo. Now I must leave the page and return to it to get the Edit option. Also, it seems a little counter intuitive to have to click the other "Edit" link to commit the changes. Wouldn't it make more sense to label that control "Save", after all, by clicking the first "Edit" I am already in Edit mode.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Sorry about the formatting. Clearly we aren't in Kansas anymore.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Usually, when you want to pause until a user has entered data, you display a modal form with the input fields. Because the form is displayed as modal, the calling form waits until it closes. You can always create a basic input form and dynamically create textboxes for the input data. If you don't want to create the controls at run time, and you know the maximum number of text entry fields then you can create them at design time and hide/show them as required.

Or, your input form could have one set of text boxes for data entry, and the user clicks an ADD button which adds the new fields to an array or collection. The only way to exit the form (other than CANCEL) is to enter the required number of items.

Again, no polling loop required.

No polling loop required.

If you want to zip and post the project I can have a look.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

When you have to modify several tables with data that has to be consistent (e.g. removing quantities from one and adding them to another) you need to use Transactions. Transactions allow you to bundle changes so that if any of the steps fails then all of the changes are undone. The steps are like

Begin Transaction

Try
    change table 1
    change table 2
    etc
    Commit Transaction
Check error
    Rollback Transaction
End Try

If you are using ADO (the method I am most familiar with) you do it like:

Dim con As New ADODB.Connection
con.Open("Driver={SQL Server};Server=.\SQLEXPRESS;Database=mydb;Trusted_Connection=yes;")

con.BeginTrans()

Try
    con.Execute("update admin set [password]='orange' where username='Eric'")
    con.Execute("update admin set [password]='staple' where username='Fred'")
    con.CommitTrans()
Catch ex As Exception
    con.RollbackTrans()
    MsgBox("rolled back")
End Try

con.Close()

If you want to try this, just create an error in the SQL statement (replace "update" with "updat" for example). The same functionality exists with OLEDB.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

The SQL statement for the update is something like (depending on your field names)

update StockTable set num_units = num_units - 25 where item_name = 'Coke'

I wasn't trying to be difficult. I just don't want to mislead you by answering a question unless I am sure what it is :)

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Try "\(\d{3}\) \d{3}-\d{4}" for the pattern. That requires a space between the area code and the number. Remove the space if you don't want it.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Please try to explain this a little clearer.

i have two textboxs which have figues in them and need the 3rd textbox to display the figure

I have no idea what you want to display in the third textbox. I also have no idea why you are using a SQL query. An example of a clearer explanation would be:

I have two text boxes, TQTY and TUP. I want to multiply the numbers in these two text boxes and display the results in a third textbox, TCOST.

In which case I would reply:

First you have to determine that TQTY and TUP both contain numeric values. A simple way to do this is with the IsNumeric function. After that you can multiply them and display the result as follows:

TCOST.Text = Convert.ToSingle(TQTY.Text) * Convert.ToSingle(TUP.text)

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

We can probably give more help if you can be more specific as to the type of search. Lacking that, it looks as if you are on the right track. SQL uses "%" and "_" for wildcarding. A good explanation with examples can be found here.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

The idea of event driven systems is to avoid polling/idling loops. Polling/idling uses CPU cycles unnecessarily and slows down anything else that may be running at the same time. One way to avoid this when you need to process several forms in succession and in a specific order is to daisy-chain the forms. When the user completes a form, either by clicking an "OK" or "NEXT" button, that form can call up the next form as part of its Close event handler. Another possibility is to create an array of form references and display them modally in a loop as in

Private myforms() as Form = {
   frmForm1,
   frmForm2,
   frmForm3
}

.
.
.

    For Each frm As Form In myforms
        If frm.ShowDialog() <> Windows.Forms.DialogResult.OK Then
            MsgBox("processing interrupted")
            Exit For
        End If
    Next

The second approach makes it easier to rearrange the order in which the forms are displayed as it decouples the forms.

A third approach is to use state transition logic in which you have a global state variable which determines which form is the next one to be displayed. The next form (or state) would be determined by the completion status of the previous form. This approach would be useful when the order of the forms is not fixed. There would be two possible "final" states - one in which all of the forms had been successfully completed, and one in which the user bailed out (or errored out).

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

I suggest you reconsider connecting via the IP address. Let the infrastructure take care of name/address translation for you and just connect using the server name. Using the IP address could impact database access in a system where clustering/mirroring provides high availability.

ryklon commented: Thanks for the tip! +1
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

You wouln't be able to use the ADO method because the fields aren't enclosed in quotes. The address field contains commas and these would be interpreted as field separators. I think the Filter option is your best bet. Read the entire file into a string array then filter on the ID plus a comma. Because this may also match something in the address portion you will still have to do a check on every line in the FIlters array to see if a line starts with the required string.

Dim alltext() As String = System.IO.File.ReadAllLines("d:\temp\test.txt")
Dim lookfor As String = "095" & ","

For Each line As String In Filter(alltext, lookfor)
    If line.StartsWith("095,") Then
        MsgBox("found " & line)
    End If
Next

I create the search string (lookfor) by concatenating an ID value with a comma. You will have to replace "095" with the variable (or textbox.Text object) containing the ID you are looking for. The "Filter" call reduces the array to only those lines containing <lookfor> in any position and the For loop find the line beginning with that value.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

There are two ways you could do it. If you have to do it ar run time then you can do

For Each ctrl As Control In Me.Controls
    If TypeOf ctrl Is OvalShape Then
        CType(ctrl,OvalShape).Size = New Size(20, 20)
    End If
Next

If you want to do it at design time you can load yourform.Designer.vb into any text editor and modify the statements in the source code (make a backup first).

Begginnerdev commented: Beat me to it. +5
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

As far as I know, not one that isn't messy (requires writing interface code). You are much better off letting SQL server do the substitution for you.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

I don't have enough info to really understand your problem or to comment on a possible solution but I do have a suggestion as to your table design.

I strongly suggest that you create a separate table that contains (minimum) two columns. One column should be the patient's name, the other should be a unique ID. The remaining tables should refer to the patient only by ID. In the event that you have two patients with the same name then a third coolumn should be added to uniquely identify a patient (birth date, address, phone number, etc). It is not a good idea to duplicate information in a database. Let's assume that you have a patient named Joanne Johnson. With your current schema, that name would appear in multiple tables. If you were to acquire a second patient with the same name you would have to modify all of your table structures to distinquish them. Also, If Joanne Johnson changes her last name (marriage, divorce, etc) then you would have to modify all records in all tables that refer to her. However, if you store the name in only one table, only that one table needs to be updated.

Another reason is that a unique ID can be generated in four bytes of storage (more if a GUID is used). A name is typically stored as a varchar and will always require more than four bytes.

A further reason is that my suggested schema divides the patient …

adam_k commented: I agree +9
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Try

For Each i As String In My.Resources.TextFile1.Split(vbCrLf)

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

I think the technique you want to use is called Gaussian Elimination. I must have written this code a half dozen times when I was back in university. I did versions with simple elimination, partial and full pivoting (actual and virtual). I hated it every time and I have long since forgotten how to do it but a walk-through with code can be found here. The technique can be used to solve for n equations in n unknowns.

And don't get me started on eigen values or linear diophantine equations. I don't recall what they are for but it is cool to be able to rattle off the names. Of course I didn't think so at exam time;)

Trivia - for matrices that are non-singular, the computer language, APL, has a single operator (quad divide) that does all that for you.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

If the two listboxes have Sorted=True then

Private Sub btnAdd_Click(sender As System.Object, e As System.EventArgs) Handles btnAdd.Click

        If ListBox1.SelectedIndex >= 0 Then
            ListBox2.Items.Add(ListBox1.SelectedItem)
            ListBox1.Items.RemoveAt(ListBox1.SelectedIndex)
        End If

    End Sub

    Private Sub btnRemove_Click(sender As System.Object, e As System.EventArgs) Handles btnRemove.Click

        If ListBox2.SelectedIndex >= 0 Then
            ListBox1.Items.Add(ListBox2.SelectedItem)
            ListBox2.Items.RemoveAt(ListBox2.SelectedIndex)
        End If

    End Sub

You can add enhancements. For example, when an item is transfered, you might want to automatically select the next item so the user can repeatedly click "ADD" or "REMOVE" to transfer consecutive items. Or you could enable multiple selection.

poojavb commented: Explained very easily... +3
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

tl;dr?

How about this

Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        Dim words() As String = Split("Some luck lies in not getting what you thought you wanted but getting what you have which once you have got it you may be smart enough to see is what you would have wanted had you known")

        For Each word As String In words
            ListBox1.Items.Add(word)
        Next

    End Sub

    Private Sub btnScan_Click(sender As System.Object, e As System.EventArgs) Handles btnScan.Click

        Dim unique As New Dictionary(Of String, Integer)

        For Each item As String In ListBox1.Items
            If unique.ContainsKey(item) Then
                unique(item) += 1
            Else
                unique(item) = 1
            End If
        Next

        For Each key As String In unique.Keys
            ListBox2.Items.Add(key & " (" & unique(key) & ")")
        Next

    End Sub

End Class

I set the Sorted property on ListBox2 to True.

powermatt commented: worked great +0
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Got it (I think). Note that the variable names are different than the last example to reflect the more generic nature of the code.

Public Class Form1

    Public ctrlArray As New Dictionary(Of String, Label)
    Public curritem As Label

    Private Sub btnAddItem_Click(sender As System.Object, e As System.EventArgs) Handles btnAddItem.Click

        'create new listbox item and associated control

        Dim key As String = "item " & ctrlArray.Count
        Dim newitem As New Label

        newitem.Location = New System.Drawing.Point(140, 13)
        newitem.Size = New System.Drawing.Size(300, 260)
        newitem.Visible = False
        newitem.Text = key

        'add the new control to the control array, then add new listitem.

        Me.Controls.Add(newitem)
        ctrlArray.Add(key, newitem)
        ListBox1.Items.Add(key)

    End Sub

    Private Sub ListBox1_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ListBox1.SelectedIndexChanged

        'hide the current visible control

        If Not curritem Is Nothing Then
            curritem.Visible = False
        End If

        'make the newly selected control visible

        If ListBox1.SelectedIndex >= 0 Then
            curritem = ctrlArray(ListBox1.SelectedItem)
            curritem.Visible = True
        End If

    End Sub

    Private Sub btnRemove_Click(sender As System.Object, e As System.EventArgs) Handles btnRemove.Click

        Dim key As String = ListBox1.SelectedItem
        curritem.Visible = False
        curritem = Nothing
        ctrlArray.Remove(key)
        ListBox1.Items.RemoveAt(ListBox1.SelectedIndex)

    End Sub

End Class

This one uses dynamic labels for testing. Replace "Label" with "PropertyGrid" or any other control. Don't forget to mark as solved if this is what you are looking for.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Try this code and see how it compares to yours

Public Class Form1

    Public ctrlArray As New Dictionary(Of Integer, PropertyGrid)
    Public currgrid As PropertyGrid

    Private Sub btnAddItem_Click(sender As System.Object, e As System.EventArgs) Handles btnAddItem.Click

        'create new listbox item and associated property grid

        Dim newitem As String = "item " & ctrlArray.Count
        Dim newprop As New PropertyGrid

        newprop.Location = New System.Drawing.Point(140, 13)
        newprop.Size = New System.Drawing.Size(300, 260)
        newprop.Visible = False

        'add the new property grid to the control array, then add new listitem.

        Me.Controls.Add(newprop)
        ctrlArray.Add(ctrlArray.Count, newprop)
        ListBox1.Items.Add(newitem)

    End Sub

    Private Sub ListBox1_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ListBox1.SelectedIndexChanged

        'hide the current visible grid

        If Not currgrid Is Nothing Then
            currgrid.Visible = False
        End If

        'make the newly selected grid visible

        currgrid = ctrlArray(ListBox1.SelectedIndex)
        currgrid.Visible = True

    End Sub

End Class

Just start with a button and listbox and nothing else.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Ah. I skipped over the most important part. "vbScript", NOT VB.Net. I'm looking at

varCampArray = split(trim(rs("Notes")) & "", ";")

If ubound(varCampArray) > 0 Then
    varCampArray2 = split(varCampArray(0) & "", "=")

and wondering if the problem is that rs("Notes") is returning some oddball value. Perhaps try

rs("Notes").Value

or try displaying the value of rs("Notes") to see what it shows.

will give rep points for intelligent and well explained responses

What are you willing to offer for help that was admittedly lacklustre;)

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

That's not a declaration. That's an assignment.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

What is your declaration for varCampArray2? My first guess would be that it is not an array but a collection. Ubound is for arrays.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

You don't use the Values keyword if the values come from a subordinate select clause.

kingsonprisonic commented: Thanks for this tips... +5
adam_k commented: True +9
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

In line 8 you have

listBox1.SelectedIndex = count - 1

But you execute this before you have added the new control to the control array. Changing the SelectedIndex triggers the event before you have added the control so when you try to access it in the array it is not there yet. Try creating the control and adding it to the array before you add the listbox entry and change the selected index.

--- first sip of morning coffee ---

On rereading I see it's complaining about index 0. Before I have a deeper look I have a question. Isn't it the new panel you want to bring to the front in which case the statement should be

ctrlArray(i).BringToFront()

instead of

Panel1.Controls.Item(i).BringToFront()

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

You can try

If frmOther.ListBox1.Items.Contains(txtMasked.Text) Then
    'login OK
Else
    MsgBox("name not found")
End If

Assuming your other form is called frmOther, etc.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Here's a sample project using Excel

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

It is certainily possible to create an array of controls. There are several ways to keep track of them. You could use a dynamic array or a dictionary (to name two). Just declare the array as follows

Dim ctrlarray(ListView1.Items.Count - 1) As PropertyGrid

You create a new instance as

ctrlarray(i) = New PropertyGrid

If you need to handle events for it you will have to use AddHandler to connect the Sub to that instance. The first Dim assumes that the number of items in the listview does not change (or at least does not increase). If the number rof items is dynamic you will have to declare the initial size as () and use ReDim as items are added. Another option is to use a dictionary as in

Dim ctrlarray as New Dictionary(Of Integer, PpropertyGrid)

And you reference properties and methods of the array items as

ctrlarray(i).etc

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

You should be using a try/catch block like this

Dim totprice As Decimal

Try
    totprice = CDec(txtPrice.Text)
    MsgBox("value is " & totprice.ToString)
Catch ex As System.InvalidCastException
    MsgBox("not a number")
End Try

If the conversion is not successful the "Catch" portion will be executed. Another way to test without Try/Catch is

If IsNumeric(txtPrice.Text) Then
    totprice = CDec(txtPrice.Text)
Else
    MsgBox("Not a number")
End If

But Try/Catch is probably better.

kingsonprisonic commented: Good solution... +5
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

That's why I suggested saving the original string in the Tag property. You don't have to worry about bogus Changed events like when the value is originally set, or if the user modifies a field, then undoes the mod. As long as the text is the same at the start and the end you don't really care if it was changed in between. By comparing the Tag to the Text all you have to do is

'pseudo code

changed = False

for each text control
    if control.Text <> control.Tag then
        changed = True
        exit for
    end if
next

If changed Then
    prompt to save changes
Else
    no changes made
End If

Easier and cleaner than having to add extra handlers and you can use a spare property in the control (Tag) instead of creating local variables.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

It looks to me like your problem is

Public myOfficerIDFolder As String = myFilesFolder & "" & frmMain.lblID.Text & ""

You are declaring and initializing the string that contains the folder name at the class level which means that it has its value set before the form even loads (uses the default value of lblID.Text). You can declare the string at the class level, but don't assign it a value until just before you actually create the folder as in

If login is successful then    'pseudo code
    myOfficerIDFolder = myFilesFolder & "" & frmMain.lblID.Text & ""
    x.CreateIDfolder()
End If
mrbungle commented: Thanks for your time! +3
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

As a matter of note, it is not necessary to do the Val(roomcost.Text). When you think about it, all that is getting passed as the sql command is a string so all that is happening is

Val(roomcost.Text)

is converting the text string (which contains a number) to an actual number. Then

& Val(roomcost.Text) &

is just converting it right back to a string. You might as well be doing

Val(roomcost.Text).ToString

So the Val() is pointless (and actually a waste of CPU unless the compiler optimizes it out).

In any case, if you have what you need then please mark this thread as solved.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

GU58 and GU67 do not appear in my copy of tnt.xls or in my combobox.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

I could have mentioned this earlier as well, but because the fields are comma delimited AND quoted, they are suitable for reading as a data source via ADO. This would allow you to read the records as if they were in a database. The ADO interface would parse the fields for you. That method looks like

Dim con As New ADODB.Connection
Dim rec As New ADODB.Recordset

con.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\;Extended Properties=""text;HDR=NO;FMT=Delimited""")
rec.Open("select * from test.txt", con, CursorTypeEnum.adOpenForwardOnly)

Do Until rec.EOF
    Debug.WriteLine(rec(0).Value & " " & rec(1).Value & " " & rec(2).Value)
    rec.MoveNext()
Loop

rec.Close()
con.Close()
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

One way to do it would be to retrieve a recordset with all the data in one query, then step through the records and copy the data to different areas depending on whether the record is for team 1 or team 2.

query = "select PlayerNumber,PlayerForename,PlayerSurname,TeamID" _
      & "  from player" _
      & " where TeamID = " & TeamID1 & " or TeamID = " & TeamID2"

Another way would be to execute two separate queries, one for each TeamID. I'm assuming TeanID is a numeric field. If string then you need single quotes around the field value.

If you want to bind the query to a control then someone else will have to step in. I'm old school ADO and SQL.

donatas commented: Brilliant, thanks! +0
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

In probably its simplest form see the attached project zip. The code is

Public Class Form1

    Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

        My.Settings.LastFile = txtFileName.Text

    End Sub

    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load

        txtFileName.Text = My.Settings.LastFile

        If My.Computer.FileSystem.FileExists(txtFileName.Text) Then
            txtFileContents.Text = My.Computer.FileSystem.ReadAllText(txtFileName.Text)
        End If

    End Sub

    Private Sub btnLoadFile_Click(sender As System.Object, e As System.EventArgs) Handles btnLoadFile.Click

        If My.Computer.FileSystem.FileExists(txtFileName.Text) Then
            txtFileContents.Text = My.Computer.FileSystem.ReadAllText(txtFileName.Text)
        End If

    End Sub

End Class
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

You could save the last loaded file name in a text file or a My.Settings string variable at form close. To do it in My.Settings, go to your project properties and the Settings section. Define a new string value (this example uses the name LastLoadedFile). When the form loads you can

lastfile = My.Settings.LastLoadedFile

Before you load the file make sure it still exists. To save the file name on form close just reverse the assignment.

kingsonprisonic commented: Good implementation.... +5
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Can you be more specific as to the client's requirements? By POS do you mean "Point Of Sale" or are you referring to a "Piece Of S**t" computer? You won't find a scanner these days that uses the old serial port - just USB. Pretty much all scanners come with software so without knkowing details as to how it will be used it is hard to offer an opinion.

Begginnerdev commented: POS computer made me laugh +5
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster
Dim prod As String = "P011112"

Dim mm As Integer = CInt(prod.Substring(1, 2))
Dim yy As Integer = CInt(prod.Substring(3, 2))

MsgBox(MonthName(mm, False) & ", " & yy + 2003)    'output is "January, 2014"

Assumes that the digits in the string are valid for conversion to date.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

As I understand it, modules are where you put general purpose code that you may want to reuse in another app. You would not put code in a module if it references forms, variables, controls, etc that exist outside the module unless those references are passed as parameters. For example, you moght create a module for a mathematical algorithm such as evaluating a polynomial or doing a custom parse of a string as long as the module uses only terms that are passed as arguments. You would not create a module that had a hard coded reference (non-passed) to an external form or control.

jlego commented: Also do not think it is a good idea to hard code much of anything if you can avoid it. +6
Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Try this

Private fadeout As Boolean
.
.
.
Private Sub btnFadeOut_Click(sender As System.Object, e As System.EventArgs) Handles btnFadeOut.Click
    fadeout = True
    Timer3.Enabled = True
End Sub

Private Sub btnFadeIn_Click(sender As System.Object, e As System.EventArgs) Handles btnFadeIn.Click
    fadeout = False
    Timer3.Enabled = True
End Sub

Private Sub Timer3_Tick(sender As Object, e As System.EventArgs) Handles Timer3.Tick

    If fadeout Then
        If Me.Opacity <= 0.0 Then
            Timer3.Enabled = False
        Else
            Me.Opacity -= 0.01
        End If
    Else
        If Me.Opacity >= 1.0 Then
            Timer3.Enabled = False
        Else
            Me.Opacity += 0.01
        End If
    End If

End Sub

My timer interval is set to 10.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Change the statement

Dim cmd As New SqlCommand("SELECT Username, Password FROM(Users) WHERE (Username = '" & UserTXT.Text & "') AND (Password = '" & PassTXT.Text & "')", con)

to remove the parentheses around the table name. The proper syntax is

select field1,field2,etc from table where etc

not

select field1,field2,etc from(table) where etc

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

I can't open your document. Don't assume everyone has Office 2010. Posting in txt format would be preferable.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

When you ask a question like that you are going to get as many different opinions as you have people responding. Everyone has their own style of coding and even that style can evolve. See Not Invented Here for an example. Please keep in mind that the following reflects my style (and opinion) only. It is not my intention to trash your code or your style. We all start at a certain level and we all (I hope) strive to improve. There are far better programmers out there than I am so there is much room for improvement in my code as well.

But you asked for comments so here goes. I'll start with the aesthetic because I believe that code should be pleasing to the eye and easy to read as well as functional.

Put a header at the top of your main module. My headers look like this:

'
'  Name:
'
'    appname
'
'  Description:
'
'    A short description of what the program does.
'
'  Usage:
'
'    If the usage is not obvious this should give some details. If it is a console
'    app then this section should explain what the parameters are.
'
'  Notes:
'
'    If the program requires any addition components, or particular versions of
'    components then this should be detailed here.
'
'  Audit:
'
'    2012-02-12  my name - original code (provide summary of changes with dates)
'

Use white …

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

One way to do it would be

Dim lines() As String = TextBox1.Lines
lines(3) = "this is actually line 4"
TextBox1.Text = Join(lines, vbCrLf)

Of course, you would get an error if you didn't have enough existing lines. n alternative would be to use a listbox instead and do

ListBox1.Items(3) = "this is line 4"

directly. Same caveat as above.

Reverend Jim 5,225 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

You could create an array of TextBox references and populate it as you create the controls as in

Public Class Form1

    Private MyText(3) As TextBox

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        For i As Integer = 0 To 3

            Dim box As New TextBox

            box.Location = New System.Drawing.Point(200, 10 + i * 25)
            box.Size = New System.Drawing.Size(50, 23)

            AddHandler box.TextChanged, AddressOf MyTextTextChanged

            MyText(i) = box
            Me.Controls.Add(box)

        Next

    End Sub

    Private Sub MyTextTextChanged(sender As System.Object, e As System.EventArgs)
        'add your code here
    End Sub

End Class

Then you can refer to the properties (such as Text) in fht eollowing way

MsgBox(MyText(2).Text)
ibeast commented: Perfectly answers my question +1