I am trying to iterate through dictionary but encounter the error "Object required". The related code is given below.
First, I create a dictionary.
Dim customers
Set customers = CreateObject("Scripting.Dictionary")
I also define class of "cCustomer", then use the dictionary like this.
Set customer = New cCustomer
customer.Init location, first, last
customers.Add location, customer
Then I use "For Each" to iterate.
Dim cc
For Each cc in customers.items
...
Next
This is OK. But I really want to declare "cc" with type.
Dim cc As cCustomer
But if I do this, VB runtime complains "Object required" at the line of "For Each". I think it is somehow related to the missing of type declaration when creating the dictionary? I am still new to VB. Thanks for the help.
MORE: why this is not duplicate...
I have tried the solution suggested by the link, namely, (a) using Dictionary instead of "Scripting.Dictionary", and (b) "Dim cc As Variant". It works as before but if I feed "cc" into a function whose argument has specific type it still fails.
Public Function foo(customer As cCustomer) As String
...
End Function
Dim cc As Variant
For Each cc in customers.items
foo(cc)
Next
The error is "ByRef argument type mismatch".
That's the reason I really need to declare "cc" as "cCustomer", but it has error of "Object required".
Dim cc As cCustomer
For Each cc In customers.items
...
Per comments
tried "Dim cc As Object", doesn't work ("Object required").
tried "remove Dim cc", doesn't work either ("ByRef argument type mismatch").
I could do "ByVal" in the function definition or use another variable, but that would involve extra copy. Something like type casting might help...
It's a bit of a cludge and there may be better ways of doing it, but how about this:
dim loc as variant
dim cc as cCustomer
for each loc in Customers
set cc = Customers(loc)
foo(cc)
next loc
It may even be possible to do foo (Customers(loc)), but I suspect you will get the type mismatch error again. I don't think you can pass an object with byval
Related
I want to insert some information into a database in VB6, but I get runtime error '91'.
My code:
Private sub btn_click()
Fname = txtFname.text
Adodc1.Recordset.AddNew
Adodc1.Recordset.Fields("Fname") = Fname
Adodc1.Recordset.Update
End sub
The debuger shows error on: Adodc.Recordset.AddNew
You haven't posted the rest of the code as to where the Adhoc1 variable is created etc...
This post suggests that the RecordSet has not been initialized prior to working with it, but it's hard to be more specific without the code.
Runtime error '91' is Object variable or With block variable not set, which is a slightly confusing way to say that your variable contains Nothing.
You either forgot to initialise the Adodc1 properly, or, and this is more likely, you need to initialise Adodc1.RecordSet to something useful (like a Set Adodc1.RecordSet = New RecordSet or related) before you can use it.
By the way you posted the code, I believe that you will populate a Recordset to insert into the database. Try as follows:
sub btn_click()
dim Adodc1 as adodb.recordset
set Adodc1 = new adodb.recordset
Fname = txtFname.text
Rs.Fields.Append "Fname", adVarChar, 20 'adVarChar = text, followed by the amount of characters
Adodc1.open()
Adodc1.Recordset.AddNew
Adodc1.Recordset.Fields("Fname") = Fname
Adodc1.Recordset.Update
End sub
I have written vbscript code to add chart in page 1 of excel for which the source is from other sheet of same excel which name is "CL.1.1" but i am getting the above error can any one help what was wrong in my below code.
Sub DispvsTime(Shname)
Sheets("Sheet1").Select
noofsheets = ActiveSheet.ChartObjects.Count
If noofsheets > 0 Then
ActiveSheet.ChartObjects.Select
ActiveSheet.ChartObjects.Delete
End If
Sheets("Sheet1").Pictures.Visible = False
ActiveSheet.Shapes.AddChart(1000, 420, 50, 500).Select
ActiveChart.ChartType = xlXYScatterSmoothNoMarkers
ActiveChart.SetSourceData Source:=Sheets(Shname).Range("G2:H2001")
ActiveChart.SetElement (msoElementChartTitleAboveChart)
ActiveChart.ChartTitle.Text = "Displacement VS Time"
End Sub
here shname is name of the sheet where data is picked.
Can any one help me to find out the bug inside the code to get this error ?
If the sheet name is Shname then place it around quotation marks, if it is a variable name, which holds the sheet name, then ignore this post :P
Sheets("Shname")
If your code is really VBScript as you say, and not VBA as it looks like, then there are several issues:
Unlike VBA you cannot use objects like ActiveSheet or ActiveChart directly in VBScript. You need a reference to these objects, usually the application object:
Set xl = CreateObject("Excel.Application")
xl.ActiveSheet.Name = "foo"
VBScript doesn't know about Excel/Office constants like xlXYScatterSmoothNoMarkers or msoElementChartTitleAboveChart, so you have to either use literal values or define those constants yourself:
Const xlXYScatterSmoothNoMarkers = 73
You can't use named arguments like Source:=... in VBScript:
xl.ActiveChart.SetSourceData xl.Sheets(Shname).Range("G2:H2001")
See here for a more detailed explanation of the differences between VBA and VBScript.
I'm porting some C# code to VB6 because legacy applications. I need to store a list of pairs. I don't need to do associative lookups, I just need to be able to store pairs of items.
The snippet I'm porting from looks like this:
List<KeyValuePair<string, string>> listOfPairs;
If I were to port this to C++, I'd use something like this:
std::list<std::pair<string, string> > someList;
If this were python I'd just use a list of tuples.
someList.append( ("herp", "derp") )
I'm looking for a library type, but will settle for something else if necessary. I'm trying to be LAZY and not have to write cYetAnotherTinyUtilityClass.cls to get this functionality, or fall back on the so-often-abused string manipulation.
I've tried googling around, but VB6 is not really documented well online, and a lot of what's there is, well challenged. If you've ever seen BigResource, you'll know what I mean.
Collections of Variants can be quite flexible and unless you are really beating on them performance is not an issue:
Private Sub SomeCode()
Dim Pair As Variant
Dim ListOfPairs As Collection
Set ListOfPairs = New Collection
With ListOfPairs
Pair = Array("this", "that")
.Add Pair
.Add Array("herp", "derp")
.Add Array("weet", "tweet")
MsgBox .Item(1)(0) 'Item index is base-1, array index base-0.
Pair = .Item(2)
MsgBox Pair(1)
ReDim Pair(1)
Pair(0) = "another"
Pair(1) = "way"
.Add Pair
MsgBox .Item(4)(1)
End With
End Sub
If its literally just for storage you can use a Type:
Public Type Tuple
Item1 As String
Item2 As String
End Type
Its a bit more concise than needing a class to do the storage.
The problem with Types (known more widely as UDTs) is that there are restrictions on what you can do with them. You can make an array of a UDT. You cannot make a collection of a UDT.
In terms of .Net they're most similar to Struct.
There's a walkthrough of the basics here or here.
I had a similar scenario and used Dictionary by including a reference to Microsoft Scripting Runtime library in my VB6 project. This was suggested by a colleague of mine and worked really well.
Dim dictionary As New Dictionary
Dim index As Integer
dictionary.Add "Index1", "value for first index"
dictionary.Add "Index2", "value for second index"
'To get the value for a key
Debug.Print dictionary("Key1")
'To get the value for all keys
For index = 0 To UBound(dictionary.Keys)
Debug.Print dictionary.Keys(index) & "=" & dictionary(dictionary.Keys(index))
Next index
List Class? (see VB section):
http://msdn.microsoft.com/en-us/library/6sh2ey19#Y0
Dictionary Class?
http://msdn.microsoft.com/en-us/library/xfhwa508
You could use a Collection
dim c as new collection
c.add "a", "b"
I am trying to check if the 'Listivew.Tag property is nothing'.
I used to do the 'Is Nothing' check universally for all scenarios as first check to avoid errors
Can someone explain how to do it in VB 6?
If Not .lvwLocation.Tag Is Nothing Then
'COMPANY
str = str & IIf(Len(.lvwLocation.Tag) > 0, " and u.location_id in " & .lvwLocation.Tag, "")
End If
Gives error 'type-mismatch'
Nothing is a valid value for Object variables, and Is is the way to compare object pointers.
But a VB6 control's Tag property is a String, and VB6's String type is not an Object; it's a primitive type. That means a String variable can't be assigned Nothing -- its emptiest possible value is the empty string. (And an Object variable can't be assigned a String value.) For strings just use the same equality/inequality/comparision operators that you use for other primitive (numeric/boolean/date) types:
If .lvwLocation.Tag <> "" Then ...
In VB6 it appears that using Is Nothing to compare Objects works, Every other data type that I tried did not. In .Net Nothing represents the default value of any data type and will work like you expect.
Dim test as Object
If Not test Is Nothing Then
/////
End If
Since it appears the data type of th Tag property in VB6 is a string. I would use something like:
If .lvwLocation.Tag <> "" Then
/////
End If
I've come across a weird scenario with the following code in a vb6 app:
Private database As dao.Database
Set database = openDaoDatabase([some valid database location], False)
createDBField database, "Table", "FirstRow", dao.dbInteger, 0, "0"
Public Sub createDBField(targetDB As dao.Database, strTable As String, strField As String, dbType As dao.DataTypeEnum, Size As Integer, strDefValue As String)
Dim td As dao.TableDef
Dim fld As dao.field
Set td = targetDB.TableDefs(strTable)
Set fld = td.CreateField(strField, dbType, 0)
If dbType = dao.DataTypeEnum.dbText Or dbType = dao.DataTypeEnum.dbMemo Then fld.AllowZeroLength = True
If strDefValue <> "" Then fld.DefaultValue = strDefValue
td.Fields.Append fld
Set td = Nothing
Set fld = Nothing
End Sub
When I step through, everything works and the new field is added to the database. However, when I simply run the application, the database becomes corrupted due to 'inconsistency'. I added some error handling and now get the error: "Unrecognized database format: [path]".
After searching the Microsoft database, I found a solution: http://support.microsoft.com/kb/238401. I'm using the Microsoft.Jet.OLEDB.4.0 provider, have SP6 installed and have a reference to the Microsoft DAO 3.6 Object Library, but it's still not working!
Any thoughts?
Update:
td.Fields.Append fld is the culprit. After removing all silent error handling, I was able to catch an error: "Run-time error 3343 Unrecognized Database Format". For some reason, I can just step over it though.
I suspect your problem is happening because of the AllowZeroLength property. I suspect the field should be added to the fields collection and the AllowZeroLength property updated.
After
td.Fields.Append fld
put something like the following:
Set tdfField = tabledef.Fields(strField)
Set prp = tdfField.CreateProperty("AllowZeroLength", dbboolean, True)
tdfField.Properties.Append prp
Note the above is aircode and not tested.
That said, it doesn't make a lot of sense to me for a text or MEMO field's AllowZeroLength property to default to True. After all, the front end user can't really visually distinguish between the NULL value and a zero length string value.
I don't see a call to database.close that might be the cause. If your VB app terminates abruptly that might leave the DB in an inconsistent state.
Which line is the error occurring on? Usually when I run into VB errors like this they are timing related. Stepping through gives enough time for something to finish processing. Try adding some sleep commands before the statement that is causing the error.