How to customize the Ribbon from code in Excel 365? - excel

I am familiar with the VBA routines needed for customising the Excel ribbon of Excel 2013 and below.
When trying to open the file on Excel 365 I get an error message:
Here is the code I use (that works on Excel 2010):
Sub CreateMenu()
' Delete the CommandBar if it exists already
On Error Resume Next
Application.CommandBars("Worksheet Menu Bar").Controls("My Tool").Delete
Set cControl = Application.CommandBars("Worksheet Menu Bar").Controls.Add
With cControl
.Caption = "My Tool"
.Style = msoButtonCaption
End With
End Sub
How should I modify the code to run on both Excel 2010 and Excel 365 versions?

Your question is actually two questions IMO.
How to make to code work for each version (differentiate between Office Versions)
How to make the code work for Office 365
I did some research on Office 365 Ribbon Customization and found a few things I hope can help.
It has become much harder to differentiate between Office versions since Office365/2019. You used to be able to just use Select Case Int(Application.Version) coupled with Case 11/14 etc. But now everything 2016 and above just returns Case 16.
I found a function to differentiate between Office Versions and also some information that CommandBars("Worksheet Menu Bar").Controls.Add has been "superseded by the new ribbon component of the Microsoft Office Fluent user interface."
I don't have Office 365 to test how to modify your code, but once you get that part working, this is how you can implement the solution:
Private Sub Workbook_Open()
If CStr(AppVersion) = 365 Then
MsgBox "Office 365" 'Setup new code here for Office365
' See --> https://learn.microsoft.com/en-us/office/vba/api/office.commandbarcontrols.add
' Note: The use of CommandBars in some Microsoft Office applications has been superseded by the new ribbon component of the Microsoft Office Fluent user interface.
' For more information, see Overview of the Office Fluent ribbon.
' https://learn.microsoft.com/en-us/office/vba/library-reference/concepts/overview-of-the-office-fluent-ribbon
Else
MsgBox "Non-Office 365" ' Insert known working code here for older versions of Office/Excel or call seperate sub for Non-Office 365
End If
End Sub
Private Function AppVersion() As Long
'Test the Office application version
'Written by Ken Puls (www.excelguru.ca)
'https://www.excelguru.ca/blog/2019/02/11/check-the-application-version-in-modern-office/
Dim registryObject As Object
Dim rootDirectory As String
Dim keyPath As String
Dim arrEntryNames As Variant
Dim arrValueTypes As Variant
Dim x As Long
Select Case Val(Application.Version)
Case Is = 16
'Check for existence of Licensing key
keyPath = "Software\Microsoft\Office\" & CStr(Application.Version) & "\Common\Licensing\LicensingNext"
rootDirectory = "."
Set registryObject = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & rootDirectory & "\root\default:StdRegProv")
registryObject.EnumValues &H80000001, keyPath, arrEntryNames, arrValueTypes
On Error GoTo ErrorExit
For x = 0 To UBound(arrEntryNames)
If InStr(arrEntryNames(x), "365") > 0 Then
AppVersion = 365
Exit Function
End If
If InStr(arrEntryNames(x), "2019") > 0 Then
AppVersion = 2019
Exit Function
End If
Next x
Case Is = 15
AppVersion = 2013
Case Is = 14
AppVersion = 2010
Case Is = 12
AppVersion = 2007
Case Else
'Too old to bother with
AppVersion = 0
End Select
Exit Function
ErrorExit:
'Version 16, but no licensing key. Must be Office 2016
AppVersion = 2016
End Function

Related

Excel VBA: Can't Access Form Control?

I'm using the latest Office 365 Excel on OS X. I've created a List Box Form Control (ActiveX controls don't seem to be available in OS X), called wb_from:
I'm trying to access this List Box from VBA using this code:
Sub my_Import()
Dim MailStr As String
MailStr = ""
If wb_from.SelectedItems.Count = 0 Then
MsgBox "No User Selected"
Exit Sub
End If
For i = 0 To (wb_from.Items.Count - 1)
If wb_from.Selected(i) Then
MailStr = MailStr & wb_from.Items.Item(i) & "; "
End If
Next i
a = 100
End Sub
Excel is giving me an object required error:
How can I correct this?
What cell did you link that control to via Format Control? That cell address should be used in your code.

Compile Error argument not optional on Mac only

I have a working Excel sheet in Excel 2010 on Windows 10 which is failing on my client's side on Excel 2011 for Mac because of the "argument not optional" error when they click on the button. Additionally, it isn't working on their end on a different computer running Office 365.
It seems to be highlighting Characters in the 6th line of code:
Sub Rectangle4_Click()
Dim xSelShp As Shape, xSelLst As Variant, I As Integer
Set xSelShp = ActiveSheet.Shapes(Application.Caller)
Set xLstBox = ActiveSheet.ListBox4
If xLstBox.Visible = False Then
xLstBox.Visible = True
xSelShp.TextFrame2.TextRange.Characters.Text = "SAVE"
Else
xLstBox.Visible = False
xSelShp.TextFrame2.TextRange.Characters.Text = "SELECT"
For I = xLstBox.ListCount - 1 To 0 Step -1
If xLstBox.Selected(I) = True Then
xSelLst = xLstBox.List(I) & ";" & xSelLst
End If
Next I
If xSelLst <> "" Then
Range("R4") = Mid(xSelLst, 1, Len(xSelLst) - 1)
Else
Range("R4") = ""
End If
End If
End Sub
The ListBox it is showing/hiding is an ActiveX ListBox.
I doubt it's relevant, but there are 40 of these Rectangle buttons in the sheet, all with near identical code, just switching 4 references.
Can anyone see what I'm missing here? Or know anything about cross-platform issues with code like this?
Thank you.
In case anyone comes across this, it does seem to be that Tim was correct and ActiveX controls do not work on a Mac. But they also did not work in Office 365. I switched this to form controls and got everything working perfectly on my client's side. My advice to my past self is to work with form controls from the beginning and avoid ActiveX at all costs if you are working on something you are sending to someone else.

ActiveDocument.SaveAs2 not working in Excel 2000 but fine in 2010 and 2016

I have used a modified version of code supplied by Jtchase08 in another thread and it works fine in Excel 2010 and 2016 when I change the object library to the relevant Microsoft word version, however in an attempt to make the same thing work in 2000 I get
Run-time error '438': Object doesn't support this property or method
Debug takes me to here
The full code I am using is below, if anyone can help modify this to work in 2000 it would be much appreciated.
Sub ExportToHTML()
Dim DocPath As String
Dim MsgBoxCompleted
Worksheets("Final Code").Activate
Worksheets("Final Code").Range("A1:A322").Select
Dim AppWord As Object
Set AppWord = CreateObject("Word.Application")
AppWord.Visible = False
Selection.Copy
DocPath = CurDir & Application.PathSeparator & Range("U15")
'Create and save txt file
AppWord.Documents.Add
AppWord.Selection.Paste
AppWord.ActiveDocument.SaveAs2 Filename:=DocPath, FileFormat:=wdFormatText
Application.CutCopyMode = False
AppWord.Quit (wdDoNotSaveChanges)
Set AppWord = Nothing
MsgBoxCompleted = MsgBox("Process complete.", vbOKOnly, "Process complete")
Worksheets("User Input").Activate
End Sub
I think the best solution would be
If Val(Application.Version) < 14 Then
AppWord.ActiveDocument.SaveAs Filename:=DocPath, FileFormat:=wdFormatText
Else
AppWord.ActiveDocument.SaveAs2 Filename:=DocPath, FileFormat:=wdFormatText
End If
So for versions before Office 2010 the old function SaveAs is used. And for Office 2010 and newer the new function SaveAs2 is used.
Information
The SaveAs2 function was introduced in Office 2010.
As I know the only difference is that the SaveAs2 function takes an additional (last) argument CompatibilityMode (see WdCompatibilityMode Enumeration).
So the old SaveAs might work in new versions as well, because it is still implemented for compatibility reasons. But we never know if it gets removed in any future versions so with the solution above you get compatibility to future versions in case the old SaveAs gets removed from VBA.

Password Protect Excel Workbook from MS Access

I need to password protect entire workbook for opening. There's no need to protect the sheets as user will do some edits once reports are generated.Code runs within MS Access. Office Version is 2003. There's no possibility of using "SAVE AS" password protect method due to certain restrictions.
Can you please point out what I am doing wrong here?
Here's what I have tried so far:
Sub testProtection()
Dim xl As New Excel.Application
Dim wkbook As Workbook
Dim fileToOpen As String
On Error GoTo ExitMe
fileToOpen = "filepath & name"
Set wkbook = xl.Workbooks.Open(fileToOpen)
error in following lines: Automation Error Object invoked has disconnection from its client
wkbook.Protect Password:="100", Structure:=True, Windows:=True
wkbook.Close savechanges:=True
ExitMe:
MsgBox err.Description
Set xl = Nothing
Set wkbook = Nothing
Call cleanAllXLInstances
End Sub
PS: It's an incentive if the workaround could be compatible with MS 2010 as the tools will be migrated in the future - but not mandatory at this point. Plus I could manage it when looking at the API later on if current code can be worked out.
All I need to make sure, at this point Display Alerts = False to suppress the alerts for Saving As file with same name in same location. Which is contradictory to the initial constraints of the question asked though...
If xlPwd <> 0 Then
wkBook.SaveAs fileName:=fileToSaveAs, Password:=xlPwd, CreateBackup:=False
wkBook.Close
strMssg = " : Report is Protected!"
Else
strErrMssg = " : Report is NOT Protected!"
isWrapped = False
GoTo ExitMe
End If

Cannot save file after upgrade to 2007 VBA

I have a sub which I call to save a file
Sub SaveToFile()
maxr = Worksheets("List").Range("H1")
Worksheets("List").Range("G1:AE" & maxr).Copy
Part of the code which is failing after an upgrade to 2007 is:
With Application.FileSearch
.LookIn = "Q:\Planning Tools\Reports\"
.Filename = "Plan_" & ThisSaveTime & ".xls"
I receive a runtime error '445' object doesn't support this action, the code then continues below:
If .Execute > 0 Then 'Existing Workbook
Application.Workbooks.Open ("Q:\Planning Tools\Reports\Plan_" & ThisSaveTime & ".xls")
ActiveWorkbook.Worksheets.Add
ActiveWorkbook.Sheets("Sheet1").Select
ActiveWorkbook.Sheets("Sheet1").Name = ThisPlanSaveName
Else 'No existing Workbook, so add one
Workbooks.Add 1
ActiveWorkbook.Sheets("Sheet1").Select
ActiveWorkbook.Sheets("Sheet1").Name = ThisPlanSaveName
End If
End With
......
End Sub
I am not sure which action is failing but can anyone see why?
Thanks
Microsoft has removed FileSearch from the Excel 2007 Object Model
There are many possible replacements like Dir and using the FileSystemObject
try these links:
Mr Excel: Replacement class for FileSearch
MSDN Communities: Application.FileSearch in Excel 2007
Ozgrid Forums - Rplacement for FileSearch
Ozgrid Forums - Application.FileSearch Replacement in Excel 2007
Execl-IT.com: Replacement for FileSearch

Resources