I have a sub that creates a Collection and adds Collections inside it. But I get an Wrong number of arguments or invalid property assignment error when adding a first collection in the loop:
Sub testState()
Dim stateCopy As State
Set stateCopy = New State
stateCopy.setStateName="some name"
stateCopy.storeBudgetWorkbooks
stateCopy.storeBudgetDatas 'error on this line
End Sub
Sub storeBudgetDatas() 'inside a class named State
...
Dim year As Integer
Dim i As Integer
i = 1
For year = 2014 To 2017
Set budgetWorkbook =
ExcelApp.Application.Workbooks.Open(budgetWorkbooks(i))
MsgBox ("still here") 'this message appears
allBudgetItems.Add getBudgetData(budgetWorkbook, year) 'this line is likely to cause problems
MsgBox ("and here") 'this message doesn't appear
budgetWorkbook.Close
i = i + 1
Next
End Sub
Function getBudgetData(budgetWorkbook As Workbook, year As Integer)
...
Dim budgetItems As Collection
Set budgetItems = getBudgetItems(year)
... 'setting attributes
getBudgetData = budgetItems(year)
End Function
Function getBudgetItems(year As Integer)
...
Dim resultCollection As Collection
Set resultCollection = New Collection
Dim itemCopy As Item
Dim i As Integer
For i = LBound(budgetItemNames) To UBound(budgetItemNames)
Set itemCopy = New Item
... 'setting attributes
resultCollection.Add itemCopy
Next
Set getBudgetItems = resultCollection
End Function
I'm not sure what's wrong here. getBudgetItems returns a collection. getBudgetData returns a collection as well. I tried adding/removing parenthesis but to no avail.
Figured it out. There should have been Set getBudgetData = budgetItems(year) instead of getBudgetData = budgetItems(year).
Since you haven't shown us all the relevant parts of your code, the best I can do is guess you're missing a Set:
Function getBudgetData(budgetWorkbook As Workbook, year As Integer)
...
Dim budgetItems As Collection
Set budgetItems = getBudgetItems(year)
... 'setting attributes
Set getBudgetData = budgetItems(year) ' Need Set here
End Function
Related
Can any one explain me to get the object entites count of the layer
using vba code acad
I think You should use SelectionSets
Public Sub SelsetByLayer()
Dim ss As AcadSelectionSet
Dim FilterType(0) As Integer
Dim FilterData(0) As Variant
FilterType(0) = 8 ' DXF code of Layer property
For I = 0 To ThisDrawing.Layers.Count
' ThisDrawing.SelectionSets.Item(0).Delete
Set ss = ThisDrawing.SelectionSets.Add("test") ' You need to ensure if such selection set not exist yet .
FilterData(0) = ThisDrawing.Layers.Item(I).Name
ss.Select acSelectionSetAll, , , FilterType, FilterData
Next
End Sub
Further to the original answer, about using selection sets.
Here it is slightly modified:
Public Sub SelsetByLayer()
Dim ss As AcadSelectionSet
Dim FilterType(0) As Integer
Dim FilterData(0) As Variant
FilterType(0) = 8 ' DXF code of Layer property
For I = 0 To ThisDrawing.Layers.Count
Set ss = CreateSelectionSet("test")
FilterData(0) = ThisDrawing.Layers.Item(I).Name
ss.Select acSelectionSetAll, , , FilterType, FilterData
Next
End Sub
Public Function CreateSelectionSet(SelName As String) As AcadSelectionSet
On Error Resume Next
' Create a new selection set
' Delete any existing selection set with the specified name
With ThisDrawing
Set CreateSelectionSet = .SelectionSets.Add(SelName)
If (Err.Number <> 0) Then
Err.Clear
.SelectionSets.Item(SelName).Delete
Set CreateSelectionSet = .SelectionSets.Add(SelName)
End If
End With
End Function
I have added in the missing method for managing the deletion of existing selection set.
ss.Count will have the number of entities found. But please bear in mind that you may have layers frozen off etc. in the drawing and I think these will be excluded from the totals.
My drawing contain 3 layers. Each of the layers contain polylines.
I need to count the total number of elements inside every layer using VBA
you can try this
Option Explicit
Sub test()
Dim myLayer As AcadLayer
For Each myLayer In ThisDrawing.Layers
MsgBox "Number of LWPolylines in layer '" & myLayer.Name & "' is: " & GetEntityTypeNumberInLayer("LWPOLYLINE", myLayer.Name)
Next myLayer
End Sub
Function GetEntityTypeNumberInLayer(entityType As String, layerName As String) As Long
Dim acSelSet As AcadSelectionSet
Dim grpCode(1) As Integer
Dim dataVal(1) As Variant
grpCode(0) = 0: dataVal(0) = entityType 'this will filter for the entity type passed with "entityType"
grpCode(1) = 8: dataVal(1) = layerName 'this will filter for layer with name as the one passed with "layerName" argument
Set acSelSet = CreateSelectionSet("sset", ThisDrawing) 'create a selection set via a proper function
acSelSet.Select acSelectionSetAll, , , grpCode, dataVal ' fill it with all elements filtered as above: LWPolylines in layer with name passed via "layername" argument
GetEntityTypeNumberInLayer = acSelSet.Count 'count the numbers of element in the selectionset
acSelSet.Delete ' delete the selection set
End Function
Function CreateSelectionSet(selsetName As String, Optional acDoc As Variant) As AcadSelectionSet
'this function returns a selection set with the given name
'if a selectionset with the given name already exists, it returns that selectionset after clearing it
'if a selectionset with the given name doesn't exist, it creates a new selectionset and returns it
Dim acSelSet As AcadSelectionSet
If IsMissing(acDoc) Then Set acDoc = ThisDrawing
On Error Resume Next
Set acSelSet = acDoc.SelectionSets.Item(selsetName) 'try to get an exisisting selection set
On Error GoTo 0
If acSelSet Is Nothing Then Set acSelSet = acDoc.SelectionSets.Add(selsetName) 'if unsuccsessful, then create it
acSelSet.Clear 'cleare the selection set
Set CreateSelectionSet = acSelSet
End Function
I got a strange issue... my if statement should work but somehow it still doesn't... I can't grasp what is wrong as it seems perfectly right. I can see that the selection is targeting the last row in the A column, and then I'm comparing it to the t_date property in my EURO_USD object which is exactly the same string as in Column("A").End(xlDown), still, it jumps to the else statement(!). Why?
Code
Option Explicit
Private Sub run() ' run the whole operation
Dim HTTP_Req As Object: Set HTTP_Req = New HTTP_Req
Dim EURO_USD As Object: Set EURO_USD = New EURO_USD
Sheets("EURO_USD").Columns("A").End(xlDown).Select
If Selection = EURO_USD.t_date Then
Debug.Print "Date already exist"
Else
Sheets("EURO_USD").Columns("A").End(xlDown).Offset(1, 0) = EURO_USD.t_date
End If
End Sub
EURO_USD Class below
Sub fetch() ' get the function o the ECB URL
Dim xDOM_nodeList As MSXML2.IXMLDOMNodeList
Dim xDom As MSXML2.DOMDocument60
Set xDom = New MSXML2.DOMDocument60
xDom.async = False
xDom.Load "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"
Do Until xDom.readyState = READYSTATE_COMPLETE
DoEvents
Loop
xDom.setProperty "SelectionNamespaces", "xmlns:f='http://www.ecb.int/vocabulary/2002-08-01/eurofxref' xmlns:c='http://www.gesmes.org/xml/2002-08-01'"
Set xDOM_nodeList = xDom.SelectNodes("//f:Cube[#currency='USD']")
Curr_ticker = Val(xDOM_nodeList.Item(0).Attributes(1).text)
Set xDOM_nodeList = xDom.SelectNodes("//f:Cube[#time]")
Curr_date = xDOM_nodeList.Item(0).Attributes(0).text
End Sub
Public Property Get ticker()
If Curr_ticker = 0 Then
Call fetch
End If
ticker = Curr_ticker
End Property
Public Property Get t_date()
If Curr_date = "" Then
Call fetch
End If
t_date = Curr_date
End Property
Remove ":"
If Selection = EURO_USD.t_date Then
Debug.Print "Date already exist"
Else
Sheets("EURO_USD").Columns("A").End(xlDown).Offset(1, 0) = EURO_USD.t_date
End If
From Rory
Your t_Date property is returning a string - what is in the cell? A real date value? Is it formatted the same as the t_Date?
Using function datevalue solved the issue.
I'm trying to save and load the data grid view column order.
I'm using this code that i suppose is also right.
Private Sub SaveColumnOrder()
Dim upperBound As Integer = Me.DataTable1DataGridView.ColumnCount - 1
Dim columnIndexes(upperBound) As String
For index As Integer = 0 To upperBound
Dim column As DataGridViewColumn = Me.DataTable1DataGridView.Columns(index)
columnIndexes(column.DisplayIndex) = index.ToString()
Next
My.Settings.GridColumnIndexes = New StringCollection
My.Settings.GridColumnIndexes.AddRange(columnIndexes)
End Sub
Private Sub LoadColumnOrder()
Dim columnIndexes As StringCollection = My.Settings.GridColumnIndexes
For displayIndex As Integer = 0 To columnIndexes.Count - 1
Dim index As Integer = CInt(columnIndexes(displayIndex))
Me.DataTable1DataGridView.Columns(index).DisplayIndex = displayIndex
Next
End Sub
Problem is that i don't know how to set the GridColumnIndexes inside project property settings.
I set to string and other "data" options but i always get the error: 'AddRange' is not a member of... {option selected}
Which is the right option in settings to make it finally work? Thank you :)
This is far beyond my skill set, frankly, I have never done anything like this and don't know if it is possible. The procedure below builds an array based on the values of column B6.
Private Sub dsbPositionBoard_Startup() Handles Me.Startup
'This event runs when the dsbPositionBoard starts. The procedure
'checks for the values in column A of the allPositionsAnualized sheet
'and populates the combobox with those values. If there are no values the box
'is disabled.
Dim xlRng As Excel.Range
Dim strRngArr As String
Dim strChkRange As String
Try
xlWB = CType(Globals.ThisWorkbook.Application.ActiveWorkbook, Excel.Workbook)
xlWS = DirectCast(xlWB.Sheets("allPositionsAnnualized"), Excel.Worksheet)
xlRng = DirectCast(xlWS.Range("B6", xlWS.Range("B6").End(Excel.XlDirection.xlDown)), Excel.Range)
strRngArr = String.Empty
strChkRange = CStr(xlWS.Range("B6").Value)
If (String.IsNullOrEmpty(strChkRange)) Then
cmbSelectPosition.Enabled = False
Else
'Build a string array delimited by commas
For i As Integer = 1 To xlRng.Rows.Count
Dim xlRngCell As Excel.Range = DirectCast(xlRng.Rows(i), Excel.Range)
strRngArr &= DirectCast(xlRngCell.Value.ToString, String) & ","
Next
strRngArr = strRngArr.Remove(strRngArr.Length - 1, 1)
cmbSelectPosition.Items.AddRange(strRngArr.Split(","c))
xlRng = Nothing
xlWS = Nothing
End If
Catch ex As Exception
MsgBox("There no positions available to select", CType(vbOKOnly, MsgBoxStyle), "Empty Selection")
End Try
End Sub
Now, the function below is used to select the value of cell range, pass it to a helper cell (B37) and then select the corresponding sheet. The value that this function passes to the helper cell has an equal value in the array above.
Private Function MoveBtwSheets(range As String) As String
'This function is used to toggle between the position board
'and the employee board. The function is utilized to select
'the employees listed in the position board, click on the radio button
' and open that employees information in the employee board
'#parameter range: Selects the cell with the employee name
Dim xlCalc As Excel.Worksheet
strMessage = "This employee does not exist. Please verify the employee name"
strCaption = "Selection Error"
msgBoxType = MessageBoxIcon.Error
msgBoxBtns = MessageBoxButtons.OK
xlWB = CType(Globals.ThisWorkbook.Application.ActiveWorkbook, Excel.Workbook)
xlCalc = CType(xlWB.Worksheets("calculationSheets"), Excel.Worksheet)
xlWSEE = CType(xlWB.Worksheets("employeeBoard"), Excel.Worksheet)
xlWSPOS = CType(xlWB.Worksheets("positionBoard"), Excel.Worksheet)
Application.ScreenUpdating = False
Try
xlCalc.Range("B36").Value = xlWSPOS.Range(range).Value
With xlWSEE
.Select()
.Range("E37").Select()
End With
Application.ScreenUpdating = True
Catch ex As Exception
MessageBox.Show(strMessage, strCaption, msgBoxBtns, msgBoxType)
End Try
Return ""
End Function
So what I wanted to do add to my function is a way to search my array for the value on B37 and then display that value in the combobox in the first procedure. Basically, instead of me dropping down and selecting the item from the array, function would search the array for me and select that item.
If I am not very clear, I can clarify or post screen shots.
This would be a great time to use LINQ. In your initial method (dsbPositionBoard_Startup()), you can add each string in Column A into a List(Of String). Then you can query the list using the value of B37 as your search parameter.
Declare the list at the top of your class (outside of any methods)
Private _myList As New List(Of String)
Add this code to your first method
strRngArr = strRngArr.Remove(strRngArr.Length - 1, 1)
cmbSelectPosition.Items.AddRange(strRngArr.Split(","c))
_myList.Add(strRngArr.Split(","c))
xlRng = Nothing
xlWS = Nothing
Now add a function along the following lines:
Private Function QueryValues(ByVal myParameter as String) As String
Dim results = From result In _myList Where result = myParameter Select result Distinct
Return results(0)
End Function
Call that function (add some error handling/null reference checks though) with your parameter being the value of cell B37 (or any cell value as string).