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

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();
}

Related

How to capture email subject lines in a column?

I have Excel VBA code that is supposed to take the subject lines from my inbox in the Lotus Notes application and then copy it into a column in Excel.
It seems to populate the subject into a single cell and over-write it.
A second issue is, half way through the loop I get an error
Type:mismatch
Sub Subject_Info()
Dim v As Object
Dim vn As Object
Dim e As Object
Dim doc As Object
Dim rtitem As Variant
Dim nit As Object
View = "$All"
Set NSession = CreateObject("Notes.NotesSession")
Set NMailDb = NSession.GetDatabase("", "")
If Not NMailDb.IsOpen Then
NMailDb.OPENMAIL
End If
Set v = NMailDb.GetView(View)
Set vn = v.CreateViewNav()
Set e = vn.GetFirstDocument()
Do While Not (e Is Nothing)
Set doc = e.Document
Set nit = doc.GetFirstItem("subject")
Lines = Split(nit.Text, vbCrLf)
Range("A:A").Resize(UBound(Lines) + 1, 1).Value = Application.WorksheetFunction.Transpose(Lines)
Set e = vn.GetNextDocument(e)
Loop
End Sub
Background: in Notes there is no fixed format for all the items that are present in a Document. One document might contain an item "Subject" whereas another one does not... and still both documents are totally valid. This is normal in a document based database in contrast to a relational database.
In your case your code line Set nit = doc.GetFirstItem("subject") will return Nothing for a document that does not contain a subject item. Then the next line will fail as well and therefor you do not have a valid array in your "Lines" variable.
You could wrap your code in a If doc.HasItem("Subject") then clause. But that makes it unnecessarily complicated as there is already a method that fits better.
Simply replace
Set nit = doc.GetFirstItem("subject")
Lines = Split(nit.Text, vbCrLf)
with
Lines = doc.GetItemValue("subject")
GetItemValue always returns an Array, independent of the existence of an item. If there is no item, then it returns an array with one empty string element.
That should solve your "Type:Mismatch" error.

Listbox Selected property causes problems

I have a listbox in a Diagram, when calling the function "drawDiagram" I want to get the selected Items of the listbox. Here is my code to do that:
Function DrawDiagram()
Dim x As Integer
Dim diaLst As ListBox
Set diaLst = ActiveSheet.ListBoxes("DiaList")
' find selected trends in List Box
For x = 0 To diaLst.ListCount - 1
If diaLst.Selected(x) = True Then
MsgBox x
End If
Next x
End Function
diaLst.ListCount correctly returns the number of Items in the list. But diaLst.Selected(x) does not work at all.
The Error message is:
German: "Die Selected-Eigenschaft des ListBox-Objektes kann nicht zugeordent werden"
English: "The Selected Property of the ListBox Object cannot be assigned" (or similar)
Does anyone know, what I did wrong?
thanks
natasia
By the way, this is the code I used to generate the list box in a chart sheet, in a separate function. At the moment when a button is clicked, the DrawDiagram function is called. The aim of the "DrawDiagram" function is to plot the selected items of the listbox in the diagram.
Set diaLst = ActiveSheet.ListBoxes.Add(ActiveChart.ChartArea.Width - 110, 5, 105, 150)
With diaLst
.Name = "DiaList"
.PrintObject = False
.MultiSelect = xlSimple
i = 2
While wTD.Cells(rowVarNames, i) <> ""
.AddItem wTD.Cells(rowVarNames, i)
i = i + 1
Wend
.Selected(3) = True
End With
first off, you must be dealing with a "Form" control (not an "ActiveX" one) otherwise you couldn't get it via .ListBoxes property of Worksheet class
I tested it in my environment (W7-Pro and Excel 2013) and found that (quite strangely to me) the Selected() property array is 1-based.
This remained even with Option Base 0 at the beginning of the module
Make sure Microsoft Forms 2.0 Object Library reference is added to your project
Function DrawDiagram()
Dim x As Long
Dim diaLst As MSForms.ListBox
Set diaLst = ActiveSheet.ListBoxes("DiaList")
' find selected trends in List Box
For x = 1 To diaLst.ListCount
If diaLst.Selected(x) = True Then
MsgBox x
End If
Next x
End Function
use Sheets("Sheet1").Shapes("List Box 1").OLEFormat.Object instead
I stumbled upon the same problem. The solution turned out to be simple, just had to tweak the code a litte bit and play around with the ListBox properites:
Function GetSelectedRowsFromListBox(lstbox As ListBox) As Collection
Create the collection
Dim coll As New Collection
Dim lst_cnt As Variant
lst_cnt = lstbox.ListCount
Dim arr_selectedVal As Variant
arr_selectedVal = lstbox.Selected
' Read through each item in the listbox
Dim i As Long
For i = 1 To lstbox.ListCount
' Check if item at position i is selected
If arr_selectedVal(i) Then
coll.Add i
End If
Next i
Set GetSelectedRowsFromListBox = coll
End Function
.Selected property returns a 1-based array with True/False values coresponding to rows in your multiple choice Form Control ListBox.
From that you can get the list of each value.
This solution is an expanded version of what is mentioned here, however this also complies with Form Control ListBox, no just ActiveX ListBox (which are 2 same but different things ;) ):
https://excelmacromastery.com/vba-listbox/
Hope that helps in the future!

How do I loop through the filter items and hide items in an Excel PivotTable using the Data Model?

I have been working with normal PivotTables in VBA, but I recently found some features on the Pivot Tables using the Data Model that I really like--mainly 'Distinct Count'. I have some code in a normal pivot table which filters the table for records 'Like' a string, and it works perfectly. How might I convert this code to the Pivot Table using the Data Model?
With ActiveSheet.PivotTables("Metrics").PivotFields("Reference number")
.Orientation = xlPageField
.Position = 1
.EnableMultiplePageItems = True
For i = 1 To .PivotItems.Count
If .PivotItems(i).Name Like "*oran*" Then
.PivotItems(i).Visible = False
End If
Next i
End With
Here is the code that is created when I record a macro and select the items to display manually under the Data Model:
ActiveSheet.PivotTables("Metrics").PivotFields("[RawData].[Status].[Status]"). _
VisibleItemsList = Array("[RawData].[Status].&[apple_434]", _
"[RawData].[Status].&[banana_689]", _
"[RawData].[Status].&[orange_1346]", _
"[RawData].[Status].&[orange_1454]")
This is the direction I am heading, but I am having some trouble accessing the VisibleItemsList Array:
With ActiveSheet.PivotTables("Metrics").PivotFields("[RawData].[Status].[Status]")
For i = 0 To UBound(.VisibleItemsList)
If i Like "*oran*" Then
i = ""
Debug.Print i
End If
Next i
End With
The output i is numeric 0,1,2,3,4 --not text, and the numbers do not seem to correspond to the number of items in the filter list. I can't figure out how to access the items, so I can show or hide the ones I want using code. I will be honest that I have not been working with arrays for very long.
I ended up using slicers to filter the data.
Dim sC As SlicerCache
Dim sL As SlicerCacheLevel
Dim aArray() As Variant
'create a slicer cache. I just used a recorded macro to get the cache code
ActiveWorkbook.SlicerCaches.Add2(ActiveSheet.PivotTables("Metrics"), _
"[RawData].[Status]").Slicers.Add ActiveSheet, "[RawData].[Status].[Status]", _
"Status", "Status", 141.75, 424.5, 144, 198.75
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Status")
Set sL = sC.SlicerCacheLevels(1) 'this will start with the first item in the slicer
With sL
For i = 1 To .Count
If sL.SlicerItems.Item(i).Name Like "*oran*" Then
GoTo nextiteration 'this will skip over anything
'like oran when saving to the array
End If
ReDim Preserve aArray(0 To i) As Variant
aArray(i) = sL.SlicerItems.Item(i).Name
nextiteration:
Next i
sC.VisibleSlicerItemsList = aArray 'this set the visible items
'= to the array you just created
'ActiveSheet.Shapes("Status").Visible = False
'to hide this slicer, uncomment the line above
End With
This Post by Paul te Braak provided the bulk of the solution. I also used this tutorial for some help with saving items to arrays. This stackoverflow answer also helped me when I needed to work with dynamic arrays. Thanks to -GregGalloway and -jeffreyweir: when looking through the links you provided, I got the idea to search for solutions using slicers.
Hey I know this is an old question, but I recently came up with a good solution for this:
<your other code goes here>
dim v as Variant, xlPT as Excel.PivotTable, str as String
str = vbNullString
set xlPT = xlBook.PivotTables("MyPivot")
with xlPT
for each v in .PivotFields("[table].[field]").PivotItems
select case Right(Left(v.Name, Len(v.Name) - 1), 4) 'my variables are 4-char strings
' But you can manipulate this piece to match your need
case "1234", "4312", "4321", "7462", "etc."
str = str & v.Name & ";"
end select
next v
.CubeFields("[table].[field]").PivotFields(1).VisibleItemsList = Split(str, ";")
end with
<the rest of your code goes here>
The key bit of knowledge here was that the CubeField object contains a PivotFields collection with just 1 member, and we can work with the VisibleItemsList in it.
Hope this helps someone in the future. Happy SO'ing

writing in excel from access line by line using vba code

Hi guys i am new here and i am new to vba.
i want to solve the following problem:
i have two different access tables. each of them contains data i want to compare first and then, if a certain constraint is true i want to import certain columns out of one of the two access db tables into an excel sheet.
what i already have: the connection to the databases, i can read the data and print them on the console via debug.print command.
i have really no idea how to write certain rows (those which conform to the constraint) to the excel sheet.
Code sample
'commandstring and data base variables stands here
'non database connection variables
Dim oldID, newID, oldBuildPlanned, newBuildPlanned As String
Dim createExcel, doesExcelExist As Boolean
Dim xl As Excel.Application
Dim wb As Excel.Workbook
Dim Wksht As Excel.Worksheet
Dim dataVar As String
Dim counter As Integer
counter = 0
createExcelSheet = False
doesSheetExist = False
'Debug.Print "TEST old database"
Do While Not objRs.EOF And Not objRs2.EOF
'Debug.Print vbTab & objRs(0) & " " & objRs(1)
'assigning database values to variables to make them comparable
oldID = objRs(counter)
newID = CStr(objRs2(counter))
oldBuildPlanned = objRs(counter + 1)
newBuildPlanned = objRs2(counter + 1)
If oldID = newID And oldBuildPlanned = newBuildPlanned Then
createExcel = True
If createExcelSheet = True And Not doesSheetExist = True Then
Set xl = New Excel.Application
Set wb = xl.Workbooks.Add
Set Wksht = ActiveWorkbook.Worksheets("Sheet1")
doesExcelExist = True
End If
Call writeReport(newID)
End If
objRs.MoveNext
objRs2.MoveNext
Loop
'tidy up stuff comes here
end of code
I am sorry if my code is not formatted as its usual, its my first post in this forum ^^
So the writeReport() should contain the code to write the data into the sheet. i planned to insert the id's of the matching database entries into the method as parameters and read these certain data out of the recordset. but i cannot convert recordset items to string, so the byRef parameter declaration causes a compile error "type mismatch". In addition i tried to export the table with DoCmd.TransferSpreadsheet, but this method exports the entire table into excel, it worked, but it is not what i am searching for.
i hope someone can help me with my little low level problem, if you need further information feel free to ask me. i am using ADO.
Thanks in advance
Welcome to the forum,
I think you might find these two websites helpful for what you are trying to do. The first one is a great tutorial on using Access and Excel together.
http://www.datawright.com.au/excel_resources/excel_access_and_ado.htm
http://www.w3schools.com/sql/default.asp
I am not sure how you are creating your recordset, by I would recommend using an SQL statement as your source. That way you only pull the data from Access that you need. If you have any more specific questions, please let me know.
Jason

Trying to pull DataField from PivotTable using VBA in Excel

I am trying to pull both a column value and a data value out of a pivot table, using Excel.
For j = 1 To 1 'pt.RowFields(i).PivotItems.Count
sum = pt.DataFields(2).PivotItems(j)
Client = pt.RowFields(1).PivotItems(j)
Sheets("InvoiceTemplate").Range("c7").Value = Client
Sheets("InvoiceTemplate").Range("i13").Value = sum
Next
The Client value comes back exactly as expected. However, the sum value throws the error:
Unable To Get PivotItems Property from PivotField class.
With a PivotTable that looks like the below, I would expect results of Contoso and £60.50
net gross
Contoso £50.00 £60.50
Adventureworks £100 £110.00
Any idea as to what I am doing wrong? By the way, I know I have a 1 TO 1 loop, but this will be modified once this is working.
I think this does what you want:
Sub PrintPivotFields()
Dim pvt As Excel.PivotTable
Dim pvtAcctField As Excel.PivotField
Dim pvtNetField As Excel.PivotField
Dim pvtItem As Excel.PivotItem
Set pvt = ActiveCell.PivotTable
Set pvtAcctField = pvt.RowFields(1)
Set pvtNetField = pvt.DataFields(1)
For Each pvtItem In pvtAcctField.PivotItems
Debug.Print pvtItem.Name
Debug.Print Intersect(pvtItem.DataRange.EntireRow, pvtNetField.DataRange).Value
Next pvtItem
End Sub
I didn't refer to this great VBA pivot table reference by Jon Peltier, but if you do you may find a better way.

Resources