How to fix late binding for datarow in datacollection where datarow variable defined in range - datarow

I'm in the process of converting VB to C#.Net for my company. In order to do this more easily, I have option strict ON. I am trying to resolve a late binding on the following code. Row is considered an OBJECT by the compiler. I've never written code in this fashion (someone else's work). Here is the code.
Dim items As List(Of Contact) = ContactsTable.GetChanges.DataTableToList(Of Contact)
'Dim row As DataRow = Nothing
Dim modifiedRows As DataRowCollection = From row In ContactsTable.Rows
Where row.RowState = DataRowState.Modified Or row.RowState = DataRowState.Added

There was no way to modify the existing code. The next best option was to recode it using a "For each" loop.
Dim modifiedRows As DataRowCollection = Nothing
For each row As DataRow In ContactsTable.Rows
If row.RowState = DataRowState.Modified Or row.RowState = DataRowState.Added Then
modifiedRows.Add(row)
End If
Next

Related

VBA Excel to MS Project

New to VBA, I am successfully importing and reading a Task List and Resources from Excel, executing VBA in Excel and inserting these records into MS Project. I am looking at setting the ActiveProject.Resources.Standardrate = "100p/h", however I am getting an error.
The code being applied (credit to previous answers provided to other related questions on Stackoverflow for the following code).
If Not ExistsInCollection (newproject.Resources, strResource) Then
newproject.resources.add.name = StrResource <-- This works, resources are added.
' However, inserting the following line:
newproject.resources.standardrate = "100p/h" <-- It errors here
End if
Any assistance is greatly appreciated - Thank you.
The code needed a minor modification to get a reference to the newly-added resource so that the StandardRate can then be updated.
This code also demonstrates how to handle the case of a list of comma-delimited resources rather than a single one.
Dim t As Task
Set t = NewProject.Tasks.Add("New task 1")
Dim StrResource As String
StrResource = "Resource 1,Resource 2,Resource 3"
Dim arrRes As Variant
arrRes = Split(StrResource, ",")
Dim i As Variant
For Each i In arrRes
If Not ExistsInCollection(NewProject.Resources, i) Then
Dim r As Resource
Set r = NewProject.Resources.Add(i)
r.StandardRate = 100
End If
t.Assignments.Add , ActiveProject.Resources(i).UniqueID
Next i

How to get the name property of the active NamedSheetView class?

Excel now has the possibility to store personal filtering views to help collaboration in simultaniously used documents.
I could only find Microsoft documentation for an add-in, but the function is available in my Excel version of MS Excel for Microsoft 365 MSO (16.0.13127.20266) 32bit.
https://learn.microsoft.com/en-us/javascript/api/excel/excel.namedsheetview?view=excel-js-preview
I am trying to store the currently applied NamedSheetView name property (for later restoring option) but
this code fails:
Dim sh1 As Worksheet
Dim xViewName As String
Set sh1 = ThisWorkbook.Sheets(Sheet6.Name)
xViewName = sh1.NamedSheetView.Name
However this code works (with previously created "Test" view):
sh1.NamedSheetViews.GetItem("Test").Activate
If this NamedSheetViews is a collection, I should be able to get the item property, but these codes also fail:
strName = sh1.NamedSheetViews.GetItem(1).Name
strName = sh1.NamedSheetViews.Item(1).Name
Anyone has ever succeeded in getting the current NamedSheetView of a Worksheet?
Here is how I probe unknown Object properties:
I start with a reference to the Object. If I don't know what the Object is I use TypeName() to return it's class name (data type). I then declare a variable of that data type. Wash, rinse and repeat as I drill down the structure. Once the variable is declared, selecting the variable and pressing F1 with open the Microsoft Help document for that data type.
Module Code
Sub WhatIsThat()
Const TestName As String = "TestName"
Dim View As NamedSheetViewCollection
Set View = Sheet6.NamedSheetViews
On Error Resume Next
View.GetItem(TestName).Delete
On Error GoTo 0
View.Add TestName
Dim SheetView As NamedSheetView
Dim n As Long
For n = 0 To View.Count - 1
Debug.Print View.GetItemAt(n).Name
Set SheetView = View.GetItemAt(n)
Debug.Print SheetView.Name
Next
Stop
End Sub
Immediate Window Tests
?TypeName(Sheet6.NamedSheetViews)
?View.GetItemAt(0).Name
?TypeName( View.GetItemAt(0))
SOLUTION:
(Thanks for the great help from TinMan)
Dim SheetView As NamedSheetView
Dim sh1 As Worksheet
Dim ActiveSheetView as string
Set sh1 = ThisWorkbook.Sheets(Sheet6.Name)
Set SheetView = sh1.NamedSheetViews.GetActive
ActiveSheetView = SheetView.Name
Application:
sh1.NamedSheetViews.GetItem(ActiveSheetView).Activate

Not case sensitive vba script

I need to make script not be case sensitive when executing if clause.. I've placed the "compare.mode=vbTextcompare not working " on different location in the script in order to solve this problem but is not working in my case... There is no error or any other problem with script.. The comparison is between a range of name all starting with capital letter but the matching part is with lower case... any solutions for this?
Sub DropDown14_Change()
Dim ScCell As Range, key
Dim Dic As Object: Set Dic = CreateObject("Scripting.Dictionary")
Set ws = Worksheets("Dashboard")
Set wsD = Worksheets("DATA")
Set complistDict = CreateObject("Scripting.Dictionary")
Dim DD14V As Variant
complistDict.RemoveAll
Dim DD14 As Object
Set complistDict = Nothing
Set complistDict = CreateObject("scripting.dictionary")
ws.Shapes("Drop Down 16").ControlFormat.RemoveAllItems
Set DD14 = ws.Shapes("Drop Down 14").OLEFormat.Object
Set DD16 = ws.Shapes("Drop Down 16").OLEFormat.Object
DD14V = DD14.List(DD14.Value)
'ws.dropdown14.Clear
For Each ScCell In wsD.Range("E2", wsD.Cells(Rows.Count, "E").End(xlUp))
Dic.CompareMode = vbTextCompare
If ScCell.Value = DD14V Then
If Not Dic.Exists(LCase(rCell.Offset(, -1).Value)) Then
Dic.Add LCase(rCell.Offset(, -1).Value), Nothing
End If
End If
Next ScCell
'MsgBox DD14.List(DD14.ListIndex)
For Each key In Dic
DD16.AddItem key
Next
End Sub
If I understand you correctly, you want to make
If ScCell.Value = DD14V Then
be case insensitive.
You can either place
Option Compare Text
at the beginning of your macro, before the first Sub statement.
Or, to limit the case insensitivity to just that line, you can use:
If Ucase(ScCell.Value) = Ucase(DD14V) Then
But your code seems to have other errors.
I would suggest you place Option Explicit at the beginning of your macro (before the first Sub) which will help with debugging.
I don't understand why MS makes NOT requiring variable declaration the default. Select Tools/Options/Editor and check Require Variable Declaration. This will place Option Explicit at the start of any new module.
It may also help to use Early binding instead of Late binding for your dictionary object to get the benefit of Intellisense.
According to this
Try to use
Option Compare Text
On top of you code.
Hope it helps!

Why is Excel VBA overwriting these object values

I am trying to create a list of objects in VBA but it seems like new objects are not being created and values are being updated to a single instance of a class.
This is the class
' ---------------------------------------------------------------
'
' Class to represent Program Increment
'
' ---------------------------------------------------------------
Public name As String
Public sprints As New Collection
This is the calling code:
' get the unique pi values
Dim piList As New Collection
For r = firstRow To lastRow
currentVal = Cells(r, 2)
On Error Resume Next
Dim currentPi As New ProgramIncrement
currentPi.name = currentVal
piList.Add currentPi, currentVal
On Error GoTo 0
Next
This is the output for the first pi
And this is the output for the second pi
I'm not seeing what I'm doing wrong base upon online documents such as this.
https://analystcave.com/vba-vba-class-tutorial/
As New creates an auto-instantiated object. Dim statements aren't executable, so there's only one object indeed.
Remove As New and use Set ... = New statements to create new objects.
Dim currentPi As ProgramIncrement
Set currentPi = New ProgramIncrement
Dim being inside the loop makes no difference - on one hand it makes it easy to later refactor and extract the loop body into its own procedure scope; on the other hand it can be read as though a new variable is created at every iteration, but that's not how scopes work in VBA: the smallest scope is procedure scope - blocks (e.g. loop bodies) don't scope anything.
This worked per Mathieu Guindon's answer.
Dim piList As New Collection
Dim currentPi As ProgramIncrement
For r = firstRow To lastRow
currentVal = Cells(r, 2)
Set currentPi = New ProgramIncrement
currentPi.name = currentVal
On Error Resume Next
piList.Add currentPi, currentVal
On Error GoTo 0
Next

Run-time error 1004 when trying to select OLAP pivotfield array element

I'm having trouble looping through the items in my OLAP pivot field. I have an array which contains the names/items I want the filter to loop through, but I cannot get the pivot field to select an array element (I want only one selected at a time)
There are many questions out there with similar problems out there, like this
and this, and I have tried to incorporate the coding to my code. However I can't seem to get it to work for me
This is my code at the moment. I have tried using currentpage rather than visibleitemlist, and instead of element just use i or industryarray(i).
Sub Test()
Dim IndustryArray() As Variant
Dim element As Variant
Dim Industry As Range
Dim Data As Variant
Dim ptITS As PivotTable
Dim pfITS As PivotField
Dim ppfITS As PivotField
Set ptITS = Worksheets("Industry Time Series").PivotTables("PivotTable1")
Set pfITS = ptITS.PivotFields("[All Industries Combined].[Industry Details].[Industry Details]")
Set ppfITS = ptITS.PageFields("[All Industries Combined].[Industry Details].[Industry Details]")
Set Industry = Worksheets("Industry List").Range("A2:A211")
ReDim IndustryArray(0 To Industry.Cells.Count + 1)
For i = 0 To Industry.Cells.Count + 1
IndustryArray(i) = "[ All Industries Combined].[Industry Details].&[" & Industry.Cells(i + 1).Value & "]"
Next i
For Each element In IndustryArray
pfITS.ClearAllFilters
pfITS.VisibleItemsList = element <-- error (for different variations as well)
Next element
End Sub
I want the filter to select each item of the array, then clear filter and move to the next item. Just get errors at the identified line.
Any help would be appreciated!
While I don’t have a VBA example I hope this C# code will help you find the problem in your code. Look for the workerFilterList_DoWork method. The relevant code is:
Excel.CubeField field = pvt.CubeFields.get_Item(args.LookIn);
field.CreatePivotFields();
field.IncludeNewItemsInFilter = false; //if this is set to true, they essentially wanted to show everything but what was specifically unchecked. With Filter List, we're doing the reverse... showing only what's spefically checked
foreach (string sLevelUniqueName in dictLevelsOfFoundMembers.Keys)
{
Excel.PivotField pivotField = (Excel.PivotField)field.PivotFields.Item(sLevelUniqueName);
if (field.Orientation == Excel.XlPivotFieldOrientation.xlPageField)
{
field.EnableMultiplePageItems = true;
}
System.Array arrNewVisibleItems = dictLevelsOfFoundMembers[sLevelUniqueName].ToArray();
pivotField.VisibleItemsList = arrNewVisibleItems;
if (field.Orientation == Excel.XlPivotFieldOrientation.xlHidden)
{
field.Orientation = Excel.XlPivotFieldOrientation.xlRowField; //if it's not in the PivotTable, then add it to rows
}
pivotField.ClearValueFilters();
pivotField.ClearLabelFilters();
}

Resources