Populate Combobox with font names - excel

I want to populate a combobox on a userform with available fonts on a pc, when the userform is initialized. i have written a code for it, but it just gives me an error:
Run-time error '-2147467259 (80004005)':
Method 'ListCount' of Object '_CommanBarComboBox' failed
Ive tried to modify the i = 1 to i = 0, but it doesnt helped me.
Private Sub UserForm_Initialize()
Image3.Visible = False
Image6.Visible = False
Dim FontList
Dim i
CreatePapers.ComboBox1.Clear
Set FontList = Application.CommandBars("Formatting").FindControl(ID:=1728)
For i = 1 To FontList.ListCount
CreatePapers.ComboBox1.AddItem FontList.List(i + 1)
Next i
End Sub
EDIT:
I modified the code, the error is gone, however, nothing is filled into the combobox.
Dim FontList As CommandBarControl
Dim i As Long
Dim Tempbar As CommandBar
CreatePapers.ComboBox1.Clear
On Error Resume Next
Set FontList = Application.CommandBars("Formatting").FindControl(ID:=1728)
' If Font control is missing, create a temp CommandBar
If FontList Is Nothing Then
Set Tempbar = Application.CommandBars.Add
Set FontList = Tempbar.Controls.Add(ID:=1728)
End If
For i = 1 To FontList.ListCount
Debug.Print FontList.List(i)
CreatePapers.ComboBox1.AddItem FontList.List(i)
Next i
Me.ComboBox1.ListIndex = 0
' Delete temp CommandBar if it exists
On Error Resume Next
Tempbar.Delete
EDIT 2:
Added 2 lines of code into the above modified code as mentioned by T.M. , but it still doesnt fill up the combobox, its just empty.
EDIT 3:
Changed some line in the code, but still it doesnt retrieves the fonts. Also the FontList is empty, even after the If FontList Is Nothing Then part, where it creates the temporary control bar.

You could shorten initializing into a more readable form by assigning a complete array to the combobox'es .List property:
Private Sub UserForm_Initialize()
Me.ComboBox1.List = GetFontList() ' << calling `GetFontList()
End Sub
The array itself is the result of the following function:
Option Explicit
Function GetFontList() As Variant
Dim FontList As CommandBarControl ' << declare type
On Error Resume Next ' provide for missing font control
Set FontList = Application.CommandBars("Formatting").FindControl(id:=1728)
On Error GoTo 0
'If Font control is missing, create it on a temporary CommandBar
If FontList Is Nothing Then
Dim tmpBar As CommandBar
Set tmpBar = Application.CommandBars.Add
Set FontList = tmpBar.Controls.Add(id:=1728)
End If
Dim tmpList: ReDim tmpList(1 To FontList.ListCount, 1 To 1)
'Assign fonts to array
Dim i As Long
For i = 1 To UBound(tmpList)
tmpList(i, 1) = FontList.List(i)
Next i
'Delete temporary CommandBar eventually
On Error Resume Next
tmpBar.Delete
'return 2-dim 1-based font array as function result
GetFontList = tmpList
End Function
Further hints
The CommandBarControl items can be addressed by a one-based index via
FontList.List(i)
*) The combobox'es 2-dimensional .List property is zero-based, but accepts also assignment of a one-based array (as returned by above function).

You are accessing a FontList item that does not exist. Your for-loop is fine. But, you need to change the line inside to:
CreatePapers.ComboBox1.AddItem FontList.List(i)
Accessing index + 1 is reaching outside of the bounds of the list, this is why it's crashing.
Your code should look like:
Private Sub UserForm_Initialize()
Image3.Visible = False
Image6.Visible = False
Dim FontList
Dim i
CreatePapers.ComboBox1.Clear
Set FontList = Application.CommandBars("Formatting").FindControl(ID:=1728)
For i = 1 To FontList.ListCount
CreatePapers.ComboBox1.AddItem FontList.List(i)
Next i
End Sub

Related

save arrays in dictionary using for loop in VBA

I have a sheet with arrays with data that I want to save in a dictionary. The column space between each array is constant and the tables are similar size. I have names on top of each array (first one in cell J3) that should be the key and the data should be the item. How can I create a loop that saves all arrays and stops when the selected range is empty?
Sub Dictionary()
Dim dictionary() As Dictionary
Dim nCol As Integer, i As Integer
nCol = 13
Sheets("Sheet1").Activate
Range(Cells(27, 11), Cells(36, 21)).Activate
For i = 1 To nCol
' dictionary(i) = Selection.Value
Selection.Offset(RowOffset:=0, ColumnOffset:=nCol).Select
Next i
End Sub
Thank you
Please, test the next code. It needs a reference to 'Microsoft Scripting Runtime':
Sub RangesIndictionary()
Dim sh As Worksheet, dict As New scripting.dictionary, nCol As Long
Dim i As Long, rngInit As Range, rngKey As Range, keyName As String
Set sh = Sheets("Sheet1")
nCol = 13
Set rngKey = sh.Range("J3")
keyName = rngKey.Value
Set rngInit = sh.Range(sh.cells(27, 11), sh.cells(36, 21))
Do While keyName <> ""
dict.Add keyName, rngInit
Set rngKey = rngKey.Offset(0, nCol)
keyName = rngKey.Value
Set rngInit = rngInit.Offset(0, nCol)
Loop
Debug.Print dict.count & " ranges have been placed in the dictionary"
Debug.Print "The first range is " & dict(sh.Range("J3").Value).Address
End Sub
It may work using Late binding, but it is better to use the reference and benefit of the intellisense suggestions.
If it is possible that the name to be the same for two such ranges, the code should preliminary check if the key exists. And you must tell us how to be treated such a situation.
In order to automatically add the necessary reference, please firstly run the next code:
Sub addScrRunTimeRef()
'Add a reference to 'Microsoft Scripting Runtime':
'In case of error ('Programmatic access to Visual Basic Project not trusted'):
'Options->Trust Center->Trust Center Settings->Macro Settings->Developer Macro Settings->
' check "Trust access to the VBA project object model"
On Error Resume Next
Application.VBE.ActiveVBProject.References.AddFromFile "C:\Windows\SysWOW64\scrrun.dll"
If err.Number = 32813 Then
err.Clear: On Error GoTo 0
MsgBox "The reference already exists...": Exit Sub
Else
On Error GoTo 0
MsgBox """Microsoft Scripting Runtime"" reference added successfully..."
End If
End Sub
It will remain only if you save the working workbook...

How do I resolve Run-time Error 438 inside a CATIA macro?

I am writing a macro in CATIA v5 using VBA. The program is suppose to take points from a geometric set and transfer them into an excel file. I have successfully gotten the excel document open, a header created, but then I receive "Run-time error '438': Object doesn't support this property or method.
I have tried searching around and it seems like the section of code is trying to interact with something outside of its domain, but I cannot figure out how. Below is a sample of my code. The line that contains "***" to the left is the line that is being pointed out in the debugger.
Dim xls As Object
Dim wkbks As Object
Dim wkbk As Object
Dim wksheets As Object
Dim sheet As Object
Dim fs, f, f1, fc, s
Dim coords(2) As Integer
Dim PartDoc
Sub CATMain()
CATIA.ActiveDocument.Selection.Search "CATGmoSearch.Point,all"
'Function Calls
AppStart
CATIAtoXLS
'wksheet.Application.ActiveWorkbook.SaveAs (ExcelFolder & Left(CATIA.ActiveDocument.Name,Len(CATIA.ActiveDocument.Name)-8)&".xls")
'wksheet.Application.ActiveWorkbook.Close
End Sub
Private Sub AppStart()
Err.Clear
On Error Resume Next
Set xls = GetObject(, "Excel.Application")
If Err.Number <> 0 Then
Err.Clear
Set xls = CreateObject("Excel.Application")
End If
xls.Application.Visible = True
Set wkbks = xls.Application.Workbooks
Set wkbk = wkbks.Add
Set wksheets = wkbk.Worksheets(1)
Set sheet = wkbk.Sheets(1)
sheet.Cells(1, "A") = "X-Cord"
sheet.Cells(1, "B") = "Y-Cord"
sheet.Cells(1, "C") = "Z-Cord"
End Sub
Private Sub CATIAtoXLS()
For i = 1 To CATIA.ActiveDocument.Selection.Count
Set Selection = CATIA.ActiveDocument.Selection ***
Set Element = Selection.Item(i)
'Transfer data to xls
Point.GetCoordinates (coords)
sheet.Cells(i + 1, "A") = coords(0)
sheet.Cells(i + 1, "B") = coords(1)
sheet.Cells(i + 1, "C") = coords(2)
Next i
End Sub
Your first issue is that in any method in CATIA VBA which passes an array as an argument, must be called on a object declared variant (explicitly or by default).
So you it should look like this:
Dim px as Variant
Set px = CATIA.ActiveDocument.Selection.Item(i).Value
Call Point.GetCoordinates(coords)
The second problem is that in VBA if you use a subroutine with parentheses, you must use the Call keyword:
Call Point.GetCoordinates (coords)
Otherwise, you can skip the parentheses and the keyword:
Point.GetCoordinates coords

VBA : Getting an error for my code "Runtime error 424"

My code is working fine but it ends up giving me a runtime error "object required.
I am not able to find out what is causing this error. This code is related to deleting graphs that don't have any data in them .
Sub HideEmptyCharts()
Dim wksCharts As Worksheet
Dim objCO As ChartObject
' Set up a variable for the worksheet containing the charts
Set wksCharts = ThisWorkbook.Sheets("Report output")
' Loop through every embedded chart object on the worksheet
For Each objCO In wksCharts.ChartObjects
' Make each one visible
objCO.Visible = True
' If the chart is empty make it not visible
If IsChartEmpty(objCO.Chart) Then objCO.Visible = False
Next objCO
End Sub
Private Function IsChartEmpty(chtAnalyse As Chart) As Boolean
Dim i As Integer
Dim j As Integer
Dim objSeries As Series
' Loop through all series of data within the chart
For i = 1 To chtAnalyse.SeriesCollection.Count
Set objSeries = chtAnalyse.SeriesCollection(i)
' Loop through each value of the series
For j = 1 To UBound(objSeries.Values)
' If we have a non-zero value then the chart is not deemed to be empty
If objSeries.Values(j) <> 0 Then
' Set return value and quit function
IsChartEmpty = False
Exit Function
End If
Next j
Next i
IsChartEmpty = True
End Function
Change the object passed to the function from Chart to full ChartObjectlike this:
Private Sub HideEmptyCharts()
Dim wksCharts As Worksheet
Dim objCO As ChartObject
Set wksCharts= ThisWorkbook.Sheets("Report output")
For Each objCO In wksCharts.ChartObjects
objCO.Visible = True
If IsChartEmpty(objCO) Then objCO.Visible = False
Next objCO
End Sub
Private Function IsChartEmpty(co As ChartObject) As Boolean
Dim i As Integer
Dim j As Integer
Dim objSeries As Series
For i = 1 To co.Chart.SeriesCollection.Count
Set objSeries = co.Chart.SeriesCollection(i)
For j = 1 To UBound(objSeries.Values)
If objSeries.Values(j) <> 0 Then
IsChartEmpty = False
Exit Function
End If
Next j
Next i
IsChartEmpty = True
End Function
An outdated pivotcache and some still remembered but in the meantime missed items caused some trouble to me in the past. So I propose to add this code once before:
Dim pc As PivotCache
For Each pc In ThisWorkbook.PivotCaches
pc.MissingItemsLimit = xlMissingItemsNone
pc.Refresh
Next pc

Excel VBA Object required error when populating ComboBox

I am getting the following error --
Run-time error '424' : Object required
Here is the code where I am getting the error message. The line where the error appears has been highlighted with ****
Sub LoadDropdown_Click()
Dim cnt As ADODB.Connection
Dim rst As ADODB.Recordset
Dim stDB As String, stSQL As String
Dim xlCalc As XlCalculation
Dim vaData As Variant
Dim k As Long
Set cnt = New ADODB.Connection
cnt.connectionString = Module1.GetConnectionString
stSQL = "EXEC dbo.GetData"
With cnt
.CursorLocation = adUseClient 'Necesary for creating disconnected recordset.
.Open stConn 'Open connection.
'Instantiate the Recordsetobject and execute the SQL-state.
Set rst = .Execute(stSQL)
End With
With rst
Set .ActiveConnection = Nothing 'Disconnect the recordset.
k = .Fields.Count
'Populate the array with the whole recordset.
vaData = .GetRows
End With
'Close the connection.
cnt.Close
'Manipulate the Listbox's properties and show the form.
With ComboBox21
.Clear ' **** the error comes at this line since ComboBox21 is empty ******
.BoundColumn = k
.List = Application.Transpose(vaData)
.ListIndex = -1
End With
Dim i As Integer
'Release objects from memory.
Set rst = Nothing
Set cnt = Nothing
End Sub
These are the things I have veified --
The ComboBox actually exists in Sheet1, called Priorities. See this screenshot showing that Sheet1 contains a Combobox called ComboBox21
The below function, LoadDropdown_Click is present in Sheet1. See this screenshot for details
This code works when running from certain machines. It used to work on my machine earlier, but now I am getting this error suddenly without having made any changes to the code or the environment.
I tried changing ComboBox21 to Sheet1.ComboBox21, but I got a compile error - Method or Data member not found.
It will be great if someone can help!
Please change your code:
With ComboBox21
.Clear ' **** the error comes at this line since ComboBox21 is empty ******
.BoundColumn = k
.List = Application.Transpose(vaData)
.ListIndex = -1
End With
'With the below:
Sheet1.ComboBox21.Clear
With Sheet1.ComboBox21
.BoundColumn = k
.List = Application.Transpose(vaData)
.ListIndex = -1
End With
Basically, you just add "On Error Resume Next" to avoid those annoying error messages popping up and then add "Err.Clear" to clear the error flag just in case.
Private Sub ComboBox1_Change()
On Error Resume Next
ComboBox5.List = Sheets("Data").Range("B1:B6").Value
Err.Clear
End Sub
NOTE: This is probably not the right way of doing things but at least it works on my end

Excel 2003, VBA not deleting all OLE/shape controls

I've written a routine that deletes checkboxes and labels which are dynamically added to a sheet. However, it doesn't realiably delete all the controls. I need to ensure they are completely removed before adding again.
Here is my routine:
Public Sub removeOLEtypesOfType()
On Error Resume Next
Dim intPass As Integer, objShape As Shape
For intPass = 1 To 2
For Each objShape In ActiveSheet.Shapes
Dim strName As String
strName = objShape.Name
If Mid(strName, 1, Len(CHECKBOX_PREFIX)) = CHECKBOX_PREFIX _
Or Mid(strName, 1, Len(LABEL_PREFIX)) = LABEL_PREFIX _
Or Mid(strName, 1, 5) = "Label" Then
objShape.Delete
End If
Next
Next
End Sub
I only added the two pass for loop to ensure the objects are deleted, but even this doesn't delete the remaining items. The issue I have is that I end up with controls that were not deleted in the workbook.
I'm only trying to delete checkboxes and labels where in the case of checkboxes the name is prefixed with:
Public Const CHECKBOX_PREFIX As String = "chkbx"
Labels are prefixed with:
Public Const LABEL_PREFIX As String = "lbl"
The 3rd search comparing with 'Label' is an attempt to mop up but even this doesn't catch all.
Is there any way to delete all shapes / ole objects within a range?
Fixed, I rewrote the sub-routine after a google search on how to delete shapes within a range:
Public Sub removeOLEtypesOfType()
On Error Resume Next
Dim objTopLeft As Range, objBotRight As Range
Dim objRange As Range, objShape As Shape
Set objRange = Sheet1.Range(COLUMN_HEADINGS)
With objRange
Set objTopLeft = .Cells(1).Address(0, 0)
Set objBotRight = .cell(.Cells.Count).Address(0, 0)
For Each objShape In ActiveSheet.Shapes
If Mid(objShape.Name, 1, Len(CHECKBOX_PREFIX)) = CHECKBOX_PREFIX _
Or Mid(objShape.Name, 1, Len(LABEL_PREFIX)) = LABEL_PREFIX Then
If Not Intersect(objTopLeft, objShape.TopLeftCell) Is Nothing And _
Not Intersect(objBotRight, objShape.BottomRightCell) Is Nothing Then
objShape.Delete
End If
End If
Next
End With
End Sub

Resources