Components:
ListBox - ListUser
ListBox - ListAccess
File - Users.txt
Public Sub AddUsers()
Dim String1 As String,S() As String
Open App.Path & "\Users.txt" For #1 As Input
Do Until EOF(1)
Line Input #1,String1
S() = Split(String1," ",2)
Form1.ListUser.Additem S(0)
Form1.ListAccess.Additem S(1)
Loop
Close #1
End Sub
.........stop posting this stuff.
You're that guy from Bnetweb, aren't you?
oh my god
Edit:
http://bnetweb.net/e107_plugins/forum/forum_viewtopic.php?11988.7
http://bnetweb.net/e107_plugins/forum/forum_viewtopic.php?11988.19
http://bnetweb.net/e107_plugins/forum/forum_viewtopic.php?11845
http://bnetweb.net/e107_plugins/forum/forum_viewtopic.php?11724.3
http://bnetweb.net/e107_plugins/forum/forum_viewtopic.php?11685.13
yes im Ratio@useast and there are people out there that are newbs to vb6 so pleasE?
And if they ask a question we will answer. Preemptive answering is called spam. Please stop.
Quote from: Ratio on August 15, 2006, 10:07 PM
.. and there are people out there that are newbs to vb6 so pleasE?
Incase you didn't notice, your a newb to VB6 aswell. In both of your posts the code you posted is poorly written.
Well, no offense, but how else would you write the code in this post so that it is not poorly written? :-P
Probably like..
Public Sub AddUsers()
Dim strLine As String, strParts() As String, intFile As Integer
intFile = FreeFile
Open App.Path & "\Users.txt" For Input As intFile
Do Until EOF(intFile)
Line Input #intFile, strLine
strParts() = Split(strLine, Space$(1), 2)
Form1.ListUser.AddItem strParts(0)
Form1.ListAccess.AddItem strParts(1)
Loop
Close intFile
End Sub
[EDIT] Also, both pieces of his code are incorrect when opening the file.
The "For [Number] As [Scope]" should be "For [Scope] As [Number]".
that still is not better code just a differnt way
No, it's better. It's still not good, though.
Quote from: rabbit on August 28, 2006, 08:42 PM
No, it's better. It's still not good, though.
Post what you'd consider "good".
The only downsides that I can see with my code, is that it could error if the program (.exe) was placed in a root directory, where App.Path would return the path along with the backslash. Also, there should probably be a check on strLine before trying to Split() it, or I could add an "& Space$(1)" after the strLine inside the Split() call.
Option Explicit
Private Type UserAccessType
strName As String
intAccess As Integer
End Type
Private arrUserList() As UserAccessType
Public Sub LoadUsers()
Dim strLine As String
Dim strParts() As String
ReDim arrUserList(0)
On Error GoTo LoadUsers_Err
Open "D:\users.txt" For Input As #1
Do Until EOF(1)
Line Input #1, strLine
strParts() = Split(strLine, " ", 2)
Call AddUser(strParts(0), strParts(1))
Loop
Close #1
Exit Sub
LoadUsers_Err:
Debug.Print "Error #" & Err.Number
Debug.Print "Error : " & Err.Description
Debug.Print "Source : " & Err.Source
Debug.Print "Help File : " & Err.HelpFile
Debug.Print "Help Context : " & Err.HelpContext
Err.Clear
End Sub
Public Sub AddUser(ByVal UserName As String, ByVal UserAccess As String)
On Error GoTo AddUser_Err
If arrUserList(UBound(arrUserList)).strName <> vbNullString Then
ReDim Preserve arrUserList(UBound(arrUserList) + 1)
End If
If UserName <> vbNullString And IsNumeric(UserAccess) Then
' assuming it's an integer, which is bad, but w/e
arrUserList(UBound(arrUserList)).strName = UserName
arrUserList(UBound(arrUserList)).intAccess = CInt(UserAccess)
Else
Debug.Print "Error: username is null or access is not numeric"
Exit Sub
End If
Exit Sub
AddUser_Err:
Debug.Print "Error #" & Err.Number
Debug.Print "Error : " & Err.Description
Debug.Print "Source : " & Err.Source
Debug.Print "Help File : " & Err.HelpFile
Debug.Print "Help Context : " & Err.HelpContext
Err.Clear
End Sub
Something of that nature, of course with the error handlers and such tailored to the program.
and rabbit for the win
Lot of unnecessary and messy code there...prone to bugs and errors.
Personally, I would not do it my self the following way, but try something along the lines of this (just wrote this up quickly did not test thoroughly)... It's basically rabbit's function cleaned up and crash free.
Private Const Config_Filename As String = ".\Config.ini"
Private Type DatabaseEntry
Usermask As String
Flags As Long
End Type
Private DatabaseUsers() As DatabaseEntry
Public Sub LoadUserDatabase()
On Error GoTo ErrorHandler
Dim FileNumber As Integer
Dim DataArray As Variant
Dim FileInput As String
'Reset our internal database list
ReDim DatabaseUsers(0)
'Local constants
Const Username = 0, Access = 1
'Get filenumber
FileNumber = FreeFile()
'Check file, set function line numbers on places where error could possibly occur for debugging purposes post compilation and release.
17: If (FileLen(Config_Filename) > 0) Then
'Open file
19: Open Config_Filename For Input As FileNumber
'Loop through the file
While EOF(FileNumber) = False
'Get our next line
23: Line Input #FileNumber, FileInput
'Split our data
25: DataArray = Split(FileInput, " ", 2)
'Check bounds of array
If (UBound(DataArray) = 1) Then
'Add user to database
29: AddDatabaseEntry DataArray(Username), DataArray(Access)
End If
Wend
'End of file, erase data
33: Erase DataArray
'Close file
Close FileNumber
End If
Exit Sub
ErrorHandler:
MsgBox "Error (LoadUserDatabase @ line " & Erl & "): " & Error(Err.Number), vbCritical Or vbMsgBoxSetForeground
Err.Clear
End Sub
Private Sub AddDatabaseEntry(ByVal Usermask As String, ByVal Flags As Long)
Dim NewSize As Long
'Get current size and one
NewSize = UBound(DatabaseUsers) + 1
'Resize our array
ReDim Preserve DatabaseUsers(0 To NewSize)
'Add entry
DatabaseUsers(NewSize).Usermask = Usermask
DatabaseUsers(NewSize).Flags = Flags
End Sub
Have not written in VB in a few months. UL FTW.
rabbit, your code isn't much better. It just has error handlers which I mistakenly left out.
Your not checking if the file exists.
Your using "#1" which could cause errors if that number is already in use for file handling.
Your not checking the size of strParts() before parsing it. Incase of a corrupt user.txt file.
Your error handling debug printout is a fair overkill.
The line "If UserName <> vbNullString And IsNumeric(UserAccess) Then" is bad coding practise because it can cause problems at times where the compiler may misinterpret this as a binary comparison. A better/more efficient equivalent would be, "If (LenB(UserName) <> 0) And (IsNumeric(UserAccess) = True) Then".
---
UL, the only comment on yours would be the naming convention ".ini" for something that isn't formatted correctly. Personally, I think it's best to stick to the .txt extension unless your specifically using .ini files to store data in there intended format.
:)
Quote from: FrOzeN on August 30, 2006, 05:45 AM
rabbit, your code isn't much better. It just has error handlers which I mistakenly left out.
Your not checking if the file exists.
Your using "#1" which could cause errors if that number is already in use for file handling.
Your not checking the size of strParts() before parsing it. Incase of a corrupt user.txt file.
Your error handling debug printout is a fair overkill.
The line "If UserName <> vbNullString And IsNumeric(UserAccess) Then" is bad coding practise because it can cause problems at times where the compiler may misinterpret this as a binary comparison. A better/more efficient equivalent would be, "If (LenB(UserName) <> 0) And (IsNumeric(UserAccess) = True) Then".
You clearly suck. IsNumeric() is BOOLEAN meaning it's either TRUE or FALSE. Checking for true is the same as checking for = true, so it doesn't matter. As for comparing the UserName variable to vbNullString, it's faster
and just as safe as using LenB(). Also, I used #1 on purpose. I always use HARD NUMBERS as opposed to variables. I always and only use (say #1) for LoadUsers(), that way the user list isn't loaded multiple times consecutively or simultaneously, and I also know that any error thrown by opening a file #1 means that something I didn't intend to happen is happening, and easily traceable.
As for checking strParts(), it's done by Split, and if there's an error, the error handler will take care of it.
And as for the error handler, you clearly missed the part where I said
Quote from: rabbit on August 29, 2006, 10:22 AMerror handlers and such tailored to the program.
I used Debug.Print for the sake of display, since I'm not writing a whole program. Do you honestly think I would use Debug.Print to handle errors in a
release? You're clearly retarded.
Quote from: FrOzeN on August 30, 2006, 05:45 AM
rabbit, your code isn't much better. It just has error handlers which I mistakenly left out.
Your not checking if the file exists.
Your using "#1" which could cause errors if that number is already in use for file handling.
Your not checking the size of strParts() before parsing it. Incase of a corrupt user.txt file.
Your error handling debug printout is a fair overkill.
The line "If UserName <> vbNullString And IsNumeric(UserAccess) Then" is bad coding practise because it can cause problems at times where the compiler may misinterpret this as a binary comparison. A better/more efficient equivalent would be, "If (LenB(UserName) <> 0) And (IsNumeric(UserAccess) = True) Then".
---
UL, the only comment on yours would be the naming convention ".ini" for something that isn't formatted correctly. Personally, I think it's best to stick to the .txt extension unless your specifically using .ini files to store data in there intended format.
:)
Programmer sets naming convention, is constant for that purpose. As for my self I don't use text files to store configuration settings--I always use the registry.
Quote from: rabbit on August 30, 2006, 10:13 AM
You clearly suck. IsNumeric() is BOOLEAN meaning it's either TRUE or FALSE. Checking for true is the same as checking for = true, so it doesn't matter. As for comparing the UserName variable to vbNullString, it's faster and just as safe as using LenB().
Ok, your line in particular isn't going to cause problems because intellisense (or whatever VB6 uses) interprets it fine. I was only saying it's bad coding practise because on other occasions there can be mix ups and it's clear to distinguish it into parts.
Also, "If someString = vbNullString" is slower than "If LenB(someString) = 0". Sure it makes pretty much makes no noticeable difference, but it's still faster.
http://www.aivosto.com/vbtips/stringopt.html
(See "The empty string")
Quote from: rabbit on August 30, 2006, 10:13 AMAs for checking strParts(), it's done by Split, and if there's an error, the error handler will take care of it.
Well with your code, if say someone has setup the users.txt and accidently input an entry at the start which is an incorrect format (without a space). Your program would get to it and then just cut out, missing out on all the others. The simply UBound() If-statement check would just ignore that entry and continue on. Essentially, if you want, you could just add an Else-statement and notify the user of the damaged entry(s).
Quote from: rabbit on August 30, 2006, 10:13 AMAnd as for the error handler, you clearly missed the part where I saidQuote from: rabbit on August 29, 2006, 10:22 AMerror handlers and such tailored to the program.
I used Debug.Print for the sake of display, since I'm not writing a whole program. Do you honestly think I would use Debug.Print to handle errors in a release? You're clearly retarded.
I'm not suggesting it was for release, it still doesn't mean you can't have overkill in your code whilst testing. There is no reason to be printing out the HelpFile/HelpContext as it's more than unlikely that you'll be referring to those files; ever.
Quote from: FrOzeN on August 30, 2006, 05:02 PM
Quote from: rabbit on August 30, 2006, 10:13 AM
You clearly suck. IsNumeric() is BOOLEAN meaning it's either TRUE or FALSE. Checking for true is the same as checking for = true, so it doesn't matter. As for comparing the UserName variable to vbNullString, it's faster and just as safe as using LenB().
Ok, your line in particular isn't going to cause problems because intellisense (or whatever VB6 uses) interprets it fine. I was only saying it's bad coding practise because on other occasions there can be mix ups and it's clear to distinguish it into parts.
You don't need to explicitly state what you expect the return of the object to be when you're dealing with booleans. It's interpreted by the language as being true if nothing conflicts with it. Honestly, in complex statements like his (Statements which contain more than one condition) it's better to remove clutter whenever you can.
Quote from: FrOzeN on August 30, 2006, 05:02 PM
Also, "If someString = vbNullString" is slower than "If LenB(someString) = 0". Sure it makes pretty much makes no noticeable difference, but it's still faster.
http://www.aivosto.com/vbtips/stringopt.html
(See "The empty string")
I really don't see how this would be a problem, even if it wasn't optimized then the difference would only be something less than a milisecond.
Quote from: FrOzeN on August 30, 2006, 05:02 PM
Quote from: rabbit on August 30, 2006, 10:13 AMAs for checking strParts(), it's done by Split, and if there's an error, the error handler will take care of it.
Well with your code, if say someone has setup the users.txt and accidently input an entry at the start which is an incorrect format (without a space). Your program would get to it and then just cut out, missing out on all the others. The simply UBound() If-statement check would just ignore that entry and continue on. Essentially, if you want, you could just add an Else-statement and notify the user of the damaged entry(s).
This is simply a difference in how to handle errors, rabbits method simply ignores the errors if they arn't function threatening, yours alerts the user of what happens. Regardless of what you or he thinks is better it isn't a very good argument to use against one's coding skill.
Quote from: FrOzeN on August 30, 2006, 05:02 PM
Quote from: rabbit on August 30, 2006, 10:13 AMAnd as for the error handler, you clearly missed the part where I saidQuote from: rabbit on August 29, 2006, 10:22 AMerror handlers and such tailored to the program.
I used Debug.Print for the sake of display, since I'm not writing a whole program. Do you honestly think I would use Debug.Print to handle errors in a release? You're clearly retarded.
I'm not suggesting it was for release, it still doesn't mean you can't have overkill in your code whilst testing. There is no reason to be printing out the HelpFile/HelpContext as it's more than unlikely that you'll be referring to those files; ever.
Honestly, when you're testing I'd Debug.Print, if something hangs the execution of the program (To the point where it cant even redraw itself) then I'd much rather have Debug.Print showing me data instead of another method.
Quote from: Warrior on August 30, 2006, 07:47 PM
Quote from: FrOzeN on August 30, 2006, 05:02 PM
Also, "If someString = vbNullString" is slower than "If LenB(someString) = 0". Sure it makes pretty much makes no noticeable difference, but it's still faster.
http://www.aivosto.com/vbtips/stringopt.html
(See "The empty string")
I really don't see how this would be a problem, even if it wasn't optimized then the difference would only be something less than a milisecond.
I just pointed that out as rabbit said it wasn't faster. Your right in that it's an unnecessary change.
Quote from: Warrior on August 30, 2006, 07:47 PM
Honestly, when you're testing I'd Debug.Print, if something hangs the execution of the program (To the point where it cant even redraw itself) then I'd much rather have Debug.Print showing me data instead of another method.
I wasn't implying not to use Debug.Print, just that the bottom 2 (of the 5 times) he used it are a bit excessive and arn't really needed.
Quote from: FrOzeN on August 31, 2006, 01:07 AM
Quote from: Warrior on August 30, 2006, 07:47 PM
Quote from: FrOzeN on August 30, 2006, 05:02 PM
Also, "If someString = vbNullString" is slower than "If LenB(someString) = 0". Sure it makes pretty much makes no noticeable difference, but it's still faster.
http://www.aivosto.com/vbtips/stringopt.html
(See "The empty string")
I really don't see how this would be a problem, even if it wasn't optimized then the difference would only be something less than a milisecond.
I just pointed that out as rabbit said it wasn't faster. Your right in that it's an unnecessary change.
Quote from: Warrior on August 30, 2006, 07:47 PM
Honestly, when you're testing I'd Debug.Print, if something hangs the execution of the program (To the point where it cant even redraw itself) then I'd much rather have Debug.Print showing me data instead of another method.
I wasn't implying not to use Debug.Print, just that the bottom 2 (of the 5 times) he used it are a bit excessive and arn't really needed.
You keep saying stuff about speed and originally used ListBoxes to hold your userlist.
Eh, I had nothing to do, so I thought i would write a new/random style access class :P
Hot or not? :)
Useage:
Add/Update users access:
Class.UserAccess("Ringo") = 100 (0 or lower access = removes user)
Get Users access:
TmpAccess = Class.UserAccess("Ringo") (0 would mean user not found)
Object Codeage:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal numbytes As Long)
Private Type udt_UserAccess
UserName As String * 20
UserHash As Long
UserAccess As Long
End Type
Private m_User() As udt_UserAccess
Private m_UserCount As Long
Private m_UserHash As Long
Private Const SizeOfUserAccess As Byte = 28
Public Sub LoadAccessFile(ByVal FilePath As String)
If Dir$(FilePath) = vbNullString Then Exit Sub
Dim FF As Integer
FF = FreeFile
Open FilePath For Binary As #FF
If LOF(FF) <= 0 Then Put #FF, 1, CLng(-1)
Get #FF, 1, m_UserCount
If m_UserCount >= 0 Then
ReDim m_User(m_UserCount)
Get #FF, 5, m_User()
End If
Close #FF
End Sub
Public Function SaveAccessFile(ByVal FilePath As String) As Boolean
On Error GoTo Err_SaveAccess
If Not Dir$(FilePath) = vbNullString Then Kill FilePath
Dim FF As Integer
If m_UserCount >= 0 Then
FF = FreeFile
Open FilePath For Binary As #FF
Put #FF, 1, m_UserCount
Put #FF, 5, m_User()
Close #FF
FF = 0
End If
SaveAccessFile = True
Exit Function
Err_SaveAccess:
SaveAccessFile = False
If FF > 0 Then Close #FF
End Function
Public Property Get UserAccess(ByVal UserName As String) As Long
If GetTrueUser(UserName) = False Then Exit Property
Dim i As Long
i = FindUser(UserName)
If i >= 0 Then
UserAccess = m_User(i).UserAccess
End If
End Property
Public Property Let UserAccess(ByVal UserName As String, ByVal NewAccess As Long)
If GetTrueUser(UserName) = False Then Exit Property
Dim i As Long
i = FindUser(UserName)
If i >= 0 Then
If NewAccess <= 0 Then 'remove the user
Call RemoveUser(i)
Else 'update the user
m_User(i).UserAccess = NewAccess
End If
Else
If NewAccess <= 0 Then Exit Property
i = m_UserCount + 1
ReDim Preserve m_User(i)
With m_User(i)
.UserName = Left$(UserName & String(20, 0), 20)
.UserHash = m_UserHash
.UserAccess = NewAccess
End With
m_UserCount = i
End If
End Property
Private Sub Class_Initialize()
m_UserCount = -1
End Sub
Private Function GetTrueUser(ByRef UserName As String) As Boolean
Dim i As Long
i = InStr(1, UserName, "#", vbTextCompare) - 1
If i > 0 Then UserName = Left$(UserName, i)
i = Len(UserName)
If i > 20 Then UserName = Left$(UserName, 20)
GetTrueUser = (i > 0)
End Function
Private Sub RemoveUser(ByRef Index As Long)
If Index < 0 Or Index > m_UserCount Then Exit Sub
Dim i As Long
If Index < m_UserCount Then
For i = Index To m_UserCount - 1
Call CopyMemory(m_User(i), m_User(i + 1), SizeOfUserAccess)
Next i
End If
m_UserCount = m_UserCount - 1
If m_UserCount < 0 Then
m_UserCount = -1
Erase m_User()
Else
ReDim Preserve m_User(m_UserCount)
End If
End Sub
Private Function FindUser(ByRef StrUser As String) As Integer
Dim i As Long
Call HashString(StrUser)
For i = 0 To m_UserCount
If m_User(i).UserHash = m_UserHash Then
If StrComp(Replace(m_User(i).UserName, vbNullChar, ""), StrUser, vbTextCompare) = 0 Then
FindUser = i
Exit Function
End If
End If
Next i
FindUser = -1
End Function
Private Sub HashString(ByRef Name As String)
Dim Key() As Byte, StrLen&, StrHash$, valHold&, i%
StrHash = LCase(Name)
StrLen = Len(StrHash)
If (StrLen Mod 4) Then
StrHash = StrHash & Left$(String(4, &H20), 4 - (StrLen Mod 4))
StrLen = Len(StrHash)
End If
ReDim Key(StrLen - 1)
Call CopyMemory(Key(0), ByVal StrHash, StrLen)
m_UserHash = 0
For i = 0 To (StrLen - 1) Step 4
valHold = (((Key(i) * 256& + Key(i + 1)) * 256& + Key(i + 2)) * 256& + Key(i + 3))
m_UserHash = m_UserHash Xor valHold
Next i
Erase Key()
End Sub
Quote from: rabbit on August 31, 2006, 09:40 AM
You keep saying stuff about speed and originally used ListBoxes to hold your userlist.
The title reads "Loading Access From A File And Splitting It", mentioning nothing about storing the info. I was just demonstrating a more appropriate way to open the file, and read from it. I just used ListUser/ListAccess as that's how he had it. If I were to create my own storage for the userlist I would build a class module.
Shut up.
In my opinion anyone that uses listboxes for reasons not nessicary should be shot.
And ratio you're bad so just keep your code to yourself. I'm only flaming you because it's true and you do the same to others.
Try storing access in a string, not an array/listbox. It's not that hard.
Edited for example below. ----v
--Don't give me this, it could error bull because theres no reason to not check for which file #s you're using--
Public sFileAccess As String
'somewhere perhaps ^
Dim sUserAccess As String
'tmp variable
Open TheFile For Input As #1
Do Until EOF(1)
Line Input #1, sUserAccess
If InstrB(2,sUserAccess,chrW$(32)) Then sFileAccess = sFileAccess & sUserAccess & ChrW$(0)
'since name must be before space, and have space so we can parse correctly.
Loop
Close #1
'Yes if access file is tampered with may return invalid results, to read...
Public Function GetAccess(sName As String) As Integer
'you could format it to lcase when storing, all up to you
If InstrB(1,LCase$(sFileAccess), LCase$(sName)) Then
Dim sTemp As String
sTemp = Mid$(sFileAccess,Instr(LCase$(sFileAccess), LCase$(sName))+1)
'gets name --->
sTemp = Mid$(sTemp, InStr(1, sTemp, ChrW$(32)) + 1)
sTemp = Left$(sTemp, InStr(1, sTemp, ChrW$(0)) - 1)
'gets access -->
'if you are always storing in 3 digits set (which I suggest to make things easier,
'you could cut the above two lines and just use
'sTemp = Mid$(sTemp, InStr(1, sTemp, ChrW$(32)) + 1, 3)
GetAccess = Val#(sTemp)
'done
End If
End Function
'storing isn't much harder either...and you can remove access using a similar method as above. No listbox, no loops, just one simple string.
Shame on you for reviving old topic, Shame on me for even talkin..
Quote from: Mystical on September 23, 2006, 04:04 PM
Shame on you for reviving old topic, Shame on me for even talkin..
Oh I didn't even notice the dates. Yeah shame on me :(
It wasn't too far down in the list so I just assumed...
lol my coding has improved by alot since this topic began