expression is a value and therefore cannot be the target of an assignment ERROR - vb.net

Dim cntrl As ComboBox = DirectCast(cboorlstCntrl, ComboBox)
Dim adors As New ADODB.Recordset
cntrl.Items.Add(adors.Fields(1))
cntrl.Items.Add(cntrl.SelectedIndex) = adors.Fields(0)
in the vb.net code above,Last line shows the error.Please solve it

The Add() method is a sub, it is no object and it doesn't return any object either. This means that it cannot be assigned to anything (which is one of the things the equal (=) operator does).
Add() takes only one parameter, which is what to add to the ComboBox's items. So if you want to add anything to a specific index you'd use the Insert() method instead:
cntrl.Items.Insert(cntrl.SelectedIndex, adors.Fields(0))
For more info, see: Insert Method (Int32, Object) - MSDN

Related

Create a ComboBox object to pass it into a Sub

I am trying to access a ComboBox on a UserForm from a sub. Therefore I'm trying to pass a Combobox object into it.
However, I don't seem to be able to create a Combobox Object in order to pass it in. They are always empty when entering the sub. This is what I've been trying:
Dim ctl As ComboBox
Set ctl = Me.cb_FcnName 'cb_FcnName is the name of the Combobox I'm trying to access
Call ColumnEntries2Combobox(ctl)
And this is my Sub:
Private Sub ColumnEntries2Combobox(ByRef Combo As ComboBox)
Combo.AddItem = Worksheets(WorksheetName).Cells(currRow, 2)
End Sub
For some reason I can't seem to find any documentation on how to create the necessary combobox object to pass into the sub...
Thanks in advance for any kind of help!
AddItem is a method, not a property. For a method we supply arguments after a space, compared to setting a property equal to something.
So change
Combo.AddItem = Worksheets(WorksheetName).Cells(currRow, 2)
to
Combo.AddItem Worksheets(WorksheetName).Cells(currRow, 2)
This is a common error, so a simple demonstration is:
object.Property = value
object.Method arg1, arg2

Access VBA listing collection items in a class module

Although I'm reasonable experienced VBA developer, I have not had the need to use class modules or collections but thought this may be my opportunity to extend my knowledge.
In an application I have a number of forms which all have the same functionality and I now need to increase that functionality. Towards that, I am trying to reorder a collection in a class module, but get an error 91 - object variable or with block not set. The collection is created when I assign events to controls. The original code I obtained from here (Many thanks mwolfe) VBA - getting name of the label in mousemove event
and has been adapted to Access. The assignments of events works well and all the events work providing I am only doing something with that control such as change a background color, change size or location on the form.
The problem comes when I want to reorder it in the collection - with a view to having an impact on location in the form. However I am unable to access the collection itself in the first place.
The below is my latest attempt and the error occurs in the collcount Get indicated by asterisks (right at the bottom of the code block). I am using Count as a test. Once I understand what I am doing wrong I should be able to manipulate it as required.
mLabelColl returns a correct count before leaving the LabelsToTrack function, but is then not found in any other function.
As you will see from the commented out debug statements, I have tried making mLabelColl Private and Dim in the top declaration, using 'Debug.Print mLabelColl.Count' in the mousedown event and trying to create a different class to store the list of labels.
I feel I am missing something pretty simple but I'm at a loss as to what - can someone please put me out of my misery
Option Compare Database
Option Explicit
'weMouseMove class module:
Private WithEvents mLbl As Access.Label
Public mLabelColl As Collection
'Dim LblList as clLabels
Function LabelsToTrack(ParamArray labels() As Variant)
Set mLabelColl = New Collection 'assign a pointer
Dim i As Integer
For i = LBound(labels) To UBound(labels)
'Set mLabelColl = New Collection events not assigned if set here
Dim LblToTrack As weMouseMove 'needs to be declared here - why?
Set LblToTrack = New weMouseMove 'assign a pointer
Dim lbl As Access.Label
Set lbl = labels(i)
LblToTrack.TrackLabel lbl
mLabelColl.Add LblToTrack 'add to mlabelcoll collection
'Set LblList as New clLabels
'LblList.addLabel lbl
Next i
Debug.Print mLabelColl.Count 'returns correct number
Debug.Print dsform.countcoll '1 - incorrect
End Function
Sub TrackLabel(lbl As Access.Label)
Set mLbl = lbl
End Sub
Private Sub mLbl_MouseDown(Button As Integer, Shift As Integer, x As Single, Y As Single)
Dim tLbl As Access.Label
'Debug.Print LblList.Count 'Compile error - Expected function or variable (Despite Count being an option
'Debug.Print mLabelColl.Count 'error 91
'Debug.Print LblList.CountLbls 'error 91
Debug.Print collCount
End Sub
Property Get collCount() As Integer
*collCount = mLabelColl.Count* 'error 91
End Property
In order to have all the weMouseMove objects reference the same collection in their mLabelColl pointer, a single line can achieve it:
LblToTrack.TrackLabel lbl
mLabelColl.Add LblToTrack
Set LblToTrack.mLabelColl = mLabelColl ' <-- Add this line.
But please be aware that this leads to a circular reference between the collection and its contained objects, a problem that is known to be a source of memory leaks, but this should not be an important issue in this case.

Return custom objects Excel VBA

I have dificulties figuring how a function can return an object in Excel VBA.
For example, in Java, I am used to write it like this:
Private ArrayList<> getARandomArrayList() {
//... My code
return anArrayList;
}
This method should return an arrayList that I can use.
If I do this in Excel, I believe it is supposed to look like this:
Function getARandomArrayList() As System.Collections.ArrayList
'... My code
getARandomArrayList = anArrayList
End Function
When I try to use this kind of function, I get a "Compile error: User-defined type not defined" error window. If I use variables type like Double or String, I have no problem. It is only with objects that I get errors.
A VBA.Collection may work for you, depending on your needs. (Edit: And as Vincent points out in the comments, no additional references are required.) Here's what it'd look like to use one:
Function getSomeCollection() As VBA.Collection
'Declare a collection
Dim newCollection As VBA.Collection
'Initialize the collection
Set newCollection = New VBA.Collection
'Add a string.
'Other methods are Item (access by index), Count, and Remove (by index)
newCollection.Add "hello"
'Reference the collection (note it's 1-based)
MsgBox newCollection(1)
'Set the return value
Set getSomeCollection = newCollection
End Function
As Rory said:
You have to set a reference to the relevant object library in order to be able to declare a variable as a type contained in it
I went in reference and activated System librairies.

Property reflection - How to get value?

I have a need to get properties and their values dynamically. My code below is failing. Can someone give me a hand? I have tried numerous examples but nothing so far.
Dim seriesName As String = s.SeriesName
If model.Settings.ShowNativeLanguage Then
Dim propInfo As System.Reflection.PropertyInfo = s.GetType().GetProperty(model.Country)
seriesName = CStr(propInfo.GetValue(s, Nothing))
End If
This code produces the error "Object does not match target type."
The question was already answered here for C# Object does not match target type using C# Reflection
The solution is to change this line of your code:
seriesName = propInfo.GetValue(propInfo, Nothing).ToString()
to this:
seriesName = propInfo.GetValue(s, Nothing).ToString()
You need to pass the object of which you want to get the value. (More information in MSDN)
Update:
You should always check reflection results for Nothing values. So first store the output of propInfo.GetValue(s, Nothing) in a temporary variable and later on only call the ToString()-function if the object is not Nothing
Surely that should be:
... propInfo.GetValue(s) ...
Normally you must pass the object representing the this instance as the first parameter. You are getting that error because it's expecting the instance s, not a PropertyInfo instance.

Ambiguous match found

I face a problem with Ambiguous match found
What I am trying to do is described in :GetType.GetProperties
In two words I am trying to run through all the properties of a control and find if user had made any changes to control's properties , then I take only the changed properties and store the values for these properties
I followed the suggestions but I get an error for propery Padding when the control is a TabControl (the tabControl has 2 tabPages).
Ok with help from Ravindra Bagale I manage to solve it:
The problem wasn't the new modifier but my stupidity:
In MSDN is says:
Situations in which AmbiguousMatchException occurs include the following:
A type contains two indexed properties that have the same name but different numbers of parameters. To resolve the ambiguity, use an overload of the GetProperty method that specifies parameter types.
A derived type declares a property that hides an inherited property with the same name, by using the new modifier (Shadows in Visual Basic). To resolve the ambiguity, use the GetProperty(String, BindingFlags) method overload and include BindingFlags.DeclaredOnly to restrict the search to members that are not inherited.
So I used BindingFlags.DeclaredOnly and the problem solved:
Private Sub WriteProperties(ByVal cntrl As Control)
Try
Dim oType As Type = cntrl.GetType
'Create a new control the same type as cntrl to use it as the default control
Dim newCnt As New Control
newCnt = Activator.CreateInstance(oType)
For Each prop As PropertyInfo In newCnt.GetType().GetProperties(BindingFlags.DeclaredOnly)
Dim val = cntrl.GetType().GetProperty(prop.Name).GetValue(cntrl, Nothing)
Dim defVal = newCnt.GetType().GetProperty(prop.Name).GetValue(newCnt, Nothing)
If val.Equals(defVal) = False Then
'So if something is different....
End If
Next
Catch ex As Exception
MsgBox("WriteProperties : " & ex.Message)
End Try
End Sub
I have to apologize.
My previous answer was wrong.
With BindingFlags.DeclaredOnly I don't get the properties that I wanted.
So I had to correct the problem with other way.
The problem occurs because two properties have the same name.
So I searched where the same named properties are different and I found that they have: have different declaringType,MetadataToken and PropertyType.
So I change the way I get the value and problem solved:
Dim val = cntrl.GetType().GetProperty(prop.Name, prop.PropertyType).GetValue(cntrl, Nothing)
Dim defVal = newCnt.GetType().GetProperty(prop.Name,prop.PropertyType).GetValue(newCnt,Nothing)
Sorry if I misguided someone.