Say I have the following enumeration:
Public Enum TimeUnit
Day
Week
Month
Year
End Enum
Is there any way I can use this enumeration to populate a ComboBox or ListBox? Ideally, I'd like the control to echo the internal representation as the inserted value (i.e. Day, not 0).
If there is a better way to go about this (c.f. 'X/Y Problem'), my basic requirement is that I must be able to use TimeUnit similarly to an enumeration, i.e. as a type in itself. I would also really like to avoid repeating myself in the code.
I am assuming you want to use the enum to pass as a value to some method. You can assign the enum value to the ItemData property, and literal values to the Item (text the user sees). I would suggest using Bob77's naming convention and writing a method to populate your combobox or listbox control. Something like below should work.
Private Sub LoadCombo()
Combo1.Clear
Combo1.AddItem "Day"
Combo1.ItemData(Combo1.NewIndex) = TimeUnit.Day
Combo1.AddItem "Week"
Combo1.ItemData(Combo1.NewIndex) = TimeUnit.Week
Combo1.AddItem "Month"
Combo1.ItemData(Combo1.NewIndex) = TimeUnit.Month
Combo1.AddItem "Year"
Combo1.ItemData(Combo1.NewIndex) = TimeUnit.Year
End Sub
Private Sub Combo1_Click()
MsgBox "You have selected " & Combo1.Text & " (" & CStr(Combo1.ItemData(Combo1.ListIndex)) & ")"
End Sub
Related
Hello i am coding in Visual Basic 6.0 and i have this error, i am trying to make a button inserting data in database.
Expected Function or variable
This is my code
Private Sub Command1_Click()
With ConString.Recordset.AddNew
!ID = txtID
!Emri = txtEmri
!Mbiemri = txtMbiemri
!Datelindja = txtData
!Telefon = !txtTelefon
!Gjinia = gender
!Punesuar = job
!Martese = cmbMartese
!Vendlindja = txtVendlindje
End With
End Sub
txtID is textbox
txtEmri is textbox
txtMbiemri is textbox
txtData is date picker
txtTelefon is textbox
gender is a string that takes value if a radio button is clicked
job is an integer if a checkbox is clicked
cmbMartese is combo box
txtVendlindje is textbox
Thank you in advance.
#JohnEason gave you the right answer. But there's another error in the line !Telefon = !txtTelefon, if I'm not mistaken. It should read !Telefon = txtTelefon, i.e. without the exclamation mark in front of txtTelefon.
I'm also not a big fan of that coding style. I prefer to not rely on default properties, but instead "spell out" the whole term, e.g.
With ConString.Recordset
.AddNew
!ID = txtID.Text
!Emri = txtEmri.Text
!Mbiemri = txtMbiemri.Text
!Datelindja = txtData.Text
!Telefon = txtTelefon.Text
' Since VB6 doesn't provide Intellisense for variables, I prefer to use some
' kind of hungarian notation for variable names, in this case sGender or strGender for a string variable
!Gjinia = gender
' Same here: iJob or intJob for an integer variable
!Punesuar = job
' You need to specify that you want the selected item of a combobox
!Martese = cmbMartese.List(cmbMartese.ListIndex)
!Vendlindja = txtVendlindje.Text
' If you're done setting column values and don't do so somewhere else,
' you also need to add a .Update statement here in order to finish the
' .AddNew action and actually persist the data to the database.
' .Update
End With
End Sub
As pointed out below by #JohnEason, there's also potentially an .Update statement missing within the With/End With block
I have made(designed) a program in Visual Basic 6.0,it consists of around 100 checkboxes ,the program does not require any code just a yes/no checkbox type program , but I want to save the checkbox state ,so that if a check box is in yes state then after restarting the program it's state remains conserved .
I have read about
My.Settings.Save but I dont know how to use it , I am using Visual Basic 6.0.
Create keys in Registry, save each checkbox value on their checkbox Change event and load the status of each of them in the form Initialize event code.
Option Explicit
Private Const MyApp As String = "My Own App" 'put here your application name
Private Const Sett As String = "Settings"
Private Sub CheckBox1_Change()
Dim chkBoxStatus As String
chkBoxStatus = "CheckBox1"
If Me.CheckBox1.value = True Then
SaveSetting MyApp, Sett, chkBoxStatus, CStr(True)
Else
SaveSetting MyApp, Sett, chkBoxStatus, CStr(False)
End If
End Sub
Do the same for all your check boxes.
And then:
Private Sub UserForm_Initialize() 'I do not remember well if VB6 uses Form_Initialize... You must adapt it accordingly.
Dim regValue As String
regValue = GetSetting(MyApp, Sett, "CheckBox1", "No value")
If regValue <> "No value" Then Me.CheckBox1.value = CBool(regValue)
'do the same for all checkboxes in discussion
'.
'.
End Sub
"No value" is returned if no value has been set in Registry (yet)...
Well, I would have made all checkboxes a control array and would save their sate in a text file in some hidden place, like C:\Users\UserName\AppData\Local. It would be a pretty small code.
Bit of a rookie issue here. How do you deal with data verification using Access Events? The problem is that when I use SetFocus to return the Cursor to the field with the errant data, Access goes through the _Exit and/or _LostFocus Events of the next Control in the Tab Order. If those include data validation procedures, the desired SetFocus is circumvented.
Using techturtles answer, I came up with this "solution" (read "hack").
Private Sub ServicingEmployee_LostFocus() 'Check data validity
If dataEntryCancelled Then Exit Sub
Dim cntrl As Control
Set cntrl = Me.ServicingEmployee
Dim myResponse As Integer
If IsNull(cntrl.Value) Then
myResponse = MsgBox("This field cannot be left blank.", vbOKOnly, "Enter Date Collected")
dataErrorInPreviousField = True
**'Next line sets a Public Control**
Set controlWithDataEntryError = Me.ServicingEmployee
End If
End Sub
Private Sub Client_GotFocus() '**Check for data Error in previous Control according to Tab Order**
If dataErrorInPreviousField Then Call dataErrorProc
End Sub
Public Sub dataErrorProc()
With controlWithDataEntryError
.SetFocus
.SelStart = 0
.SelLength = Len(.Text)
End With
dataErrorInPreviousField = False
End Sub
Private Sub Client_Exit(Cancel As Integer) '**Example of Bypassing _Exit Event**
If dataEntryCancelled Or dataErrorInPreviousField Then Exit Sub
.
...
End Sub
My question is this: Is there a simpler way to accomplish this?
First, I would strongly encourage you to add table constraints in addition to your form validation, if you haven't already done so. Assuming this form is tied to a table in Access, just make sure the ServicingEmployee field (in the table) is set to required. That way, you have another level of validation making sure the field has a value.
For form validation, you can use either the form's or control's BeforeUpdate event. If you use the form's event, you only have to run the check once.
I would also suggest having a separate function (within the form) to check validity. Something like this (here, I'm using a form tied to an Employees table, with a first name and last field which should both be non-null):
Private Function isFormValid() As Boolean
' we start off assuming form is valid
isFormValid = True
If IsNull(Me.txtFirstName) Then
MsgBox "First name cannot be blank", vbOKOnly
Me.txtFirstName.SetFocus
isFormValid = False
ElseIf IsNull(Me.txtLastName) Then
MsgBox "Last name cannot be blank", vbOKOnly
Me.txtLastName.SetFocus
isFormValid = False
End If
End Function
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Not isFormValid Then
Cancel = 1
End If
End Sub
I am currently trying to add to my VB6 combobox using the AddItem method. This works, however, I want to display text in the drop down but I need to pass the ID of that text.
Is there a way to accomplish this by using the AddItem method?
It can't be done in the AddItem method but it's fairly easy to do it immediately after, using the NewIndex property, as long as the ID is a numeric value:
With Combo1
For i = 16 To 34
.AddItem "Item " & i
.ItemData(.NewIndex) = i
Next
End With
As the ID was not numeric I didn't use the solution above.
I had to create a type that had a "desc" and an "cod" and then create an array of that type.
I then used the ListIndex of the drop down (populated by the array) to get the element value which contained the id.
Private Type T_arrType
cod As String
dsc As String
End Type
dim x as integer
x = cbo.listIndex
msgbox(strArr(x).cod)
msgbox(strArr(x).dsc)
It's quite a simple question - how do I sort a collection?
I've got a CSV file with rows in a random order. I'd like to sort the rows according to the date in one column. Do I add the rows to a recordset? Can I sort with a Scripting.Dictionary?
I've clearly been spoilt with .NET and Linq, and now I find myself back in the land of classic asp, realising I must have known this 7 years ago, and missing generics immensely. I feel like a complete n00b.
In this case I would get help from big brother .net. It's possible to use System.Collections.Sortedlist within your ASP app and get your key value pairs sorted.
set list = server.createObject("System.Collections.Sortedlist")
with list
.add "something", "YY"
.add "something else", "XX"
end with
for i = 0 to list.count - 1
response.write(list.getKey(i) & " = " & list.getByIndex(i))
next
Btw if the following .net classes are available too:
System.Collections.Queue
System.Collections.Stack
System.Collections.ArrayList
System.Collections.SortedList
System.Collections.Hashtable
System.IO.StringWriter
System.IO.MemoryStream;
Also see: Marvels of COM .NET interop
I'd go with the RecordSet approach. Use the Text Driver. You'll need to change the directory in the connection string and the filename in the select statement. the Extended Property "HDR=Yes" specifies that there's a header row in the CSV which I suggest as it will make writing the psuedo SQL easier.
<%
Dim strConnection, conn, rs, strSQL
strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\inetpub\wwwroot\;Extended Properties='text;HDR=Yes;FMT=Delimited';"
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open strConnection
Set rs = Server.CreateObject("ADODB.recordset")
strSQL = "SELECT * FROM test.csv order by date desc"
rs.open strSQL, conn, 3,3
WHILE NOT rs.EOF
Response.Write(rs("date") & "<br/>")
rs.MoveNext
WEND
rs.Close
Set rs = Nothing
conn.Close
Set conn = Nothing
%>
It's been a long time for me too. IIRC you don't have an option out of the box.
If I were you I'd put all the data in an array and then sort the array. I found a QuickSort implementation here: https://web.archive.org/web/20210125130007/http://www.4guysfromrolla.com/webtech/012799-3.shtml
Also look at the "Bubble Sort", works excellent with those classic asp tag cloud.
https://web.archive.org/web/20180927040044/http://www.4guysfromrolla.com:80/webtech/011001-1.shtml
A late late answer to this, but still of value.
I was working with small collections so could afford the approach where I inserted the item in the correct place on each occasion, effectively reconstructing the collection on each addition.
The VBScript class is as follows:
'Simple collection manager class.
'Performs the opration of adding/setting a collection item.
'Encapulated off here in order to delegate responsibility away from the collection class.
Class clsCollectionManager
Public Sub PopulateCollectionItem(collection, strKey, Value)
If collection.Exists(strKey) Then
If (VarType(Value) = vbObject) Then
Set collection.Item(strKey) = Value
Else
collection.Item(strKey) = Value
End If
Else
Call collection.Add(strKey, Value)
End If
End Sub
'take a collection and a new element as input parameters, an spit out a brand new collection
'with the new item iserted into the correct location by order
'This works on the assumption that the collection it is receiving is already ordered
'(which it should be if we always use this method to populate the item)
'This mutates the passed collection, so we highlight this by marking it as byref
'(this is not strictly necessary as objects are passed by reference anyway)
Public Sub AddCollectionItemInOrder(byref existingCollection, strNewKey, Value)
Dim orderedCollection: Set orderedCollection = Server.CreateObject("Scripting.Dictionary")
Dim strExistingKey
'If there is something already in our recordset then we need to add it in order.
'There is no sorting available for a collection (or an array) in VBScript. Therefore we have to do it ourself.
'First, iterate over eveything in our current collection. We have to assume that it is itself sorted.
For Each strExistingKey In existingCollection
'if the new item doesn't exist AND it occurs after the current item, then add the new item in now
'(before adding in the current item.)
If (Not orderedCollection.Exists(strNewKey)) And (strExistingKey > strNewKey) Then
Call PopulateCollectionItem(orderedCollection, strNewKey, Value)
End If
Call PopulateCollectionItem(orderedCollection, strExistingKey, existingCollection.item(strExistingKey))
Next
'Finally check to see if it still doesn't exist.
'It won't if the last place for it is at the very end, or the original collection was empty
If (Not orderedCollection.Exists(strNewKey)) Then
Call PopulateCollectionItem(orderedCollection, strNewKey, Value)
End If
Set existingCollection = orderedCollection
End Sub
End Class