I've run into a bit of a problem with making my macros compatible with OSX where it works on windows.
I have the following issue:
Compile error: Can't find project or library error when running the macro on Office 2016 on a MAC
The code/ function is used to change specific ranges to Upper Case / Proper case. The debugger highlights "UCase(Cell)" and "Cell"
Sub ChkSheet()
'=========================================================================
' Format the cell boarders when the info needs to be corrected or updated
'=========================================================================
Dim historyWks As Worksheet
Set historyWks = Worksheets("Namelist")
Dim lRow As Long
Dim emailRng As Range
Dim Cell As Range
With historyWks
' Flags cells where the Email fieldcontains invalid characters
lRow = Range("G" & Rows.Count).End(xlUp).Row
Set emailRng = Range("Q2:Q" & lRow)
For Each Cell In emailRng
If Cell.Value = "," _
Or Cell.Value = " " _
Or Cell.Value = "wd" _
Or Cell.Value = "" _
Or Cell.Find("#") Is Nothing Then
Cell.Interior.Color = vbRed
Else:
Cell.Interior.ColorIndex = 0
End If
Next
'Change the text case
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
For Each Cell In Range("NListUpper")
Select Case True
Case Application.IsText(Cell) = True
Cell = UCase(Cell)
End Select
Next Cell
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
'Change the case to proper
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
For Each Cell In Range("NListProp")
Select Case True
Case Application.IsText(Cell) = True
Cell = StrConv(Cell, vbProperCase)
End Select
Next Cell
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End With
End Sub
I've noticed that some libraries are missing on Excel 2016 on OSX and i'm aware that MS has dropped many libraries out of Excel for OSX.
Any advice on this would be just great.
Can you try avoiding using default properties of the Range object - they might differ between Windows and OSX:
So, instead of:
Select Case True
Case Application.IsText(Cell) = True
Cell = UCase(Cell)
End Select
Can you just try:
If Application.IsText(Cell.Value) Then
Cell.Value = UCase(Cell.Value)
End If
Related
I am trying to rewrite my windows VBA code so i can use it on a Mac computer.
But somehow it is not possible to load the information into an active worksheet on mac.
Where MyFiles is the csv file opened by the code of http://www.rondebruin.nl/mac/mac015.html
.
I broke down the code a bit because i thought it didn't recognize the workbook. But i think the problem lies in the work book.
Set ws = ActiveWorkbook.Sheets("1. Pledges (ruw)")
MyFiles = MacScript(MyScript)
On Error GoTo 0
If MyFiles <> "" Then
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
With ws.QueryTables.Add(Connection:="TEXT;" & MyScript, Destination:=ws.Range("A1"))
.TextFileParseType = xlDelimited
.TextFileCommaDelimiter = True
.Refresh
End With
If ws.Range("A2").Value = vbNullString Then
ws.rows("2").EntireRow.Delete
End If
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End If
End Sub
Some how it always crashes on the .refresh even if i use the code of robin the bruijn i can't use the querytables which work perfectly on windows.
Original windows code:
Dim ws As Worksheet, strFile As String
Set ws = ActiveWorkbook.Sheets("1. Pledges (ruw)") 'set to current worksheet name
strFile = Application.GetOpenFilename("Text Files (*.csv),*.csv", , "Please selec text file...")
With ws.QueryTables.Add(Connection:="TEXT;" & strFile, Destination:=ws.Range("A1"))
.TextFileParseType = xlDelimited
.TextFileCommaDelimiter = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.SaveData = True
End With
If ws.Range("A2").Value = vbNullString Then
ws.rows("2").EntireRow.Delete
End If
I have a code which I would like to use on multiple sheets, except one sheet. But applying the code to alle sheets is also fine.
Here is the code that I would like to adjust. I am have currently applied it to Excel 2011 in OS X , but I would like to use it for Excel 2010 in Windows.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Then
Dim the_selection As String
Dim month_in_review As String
the_selection = Sheet1.Range("A1")
Dim Rep As Integer
For Rep = 2 To 379
the_column = GetColumnLetter_ByInteger(Rep)
month_in_review = Sheet1.Range(the_column & "1")
If the_selection = month_in_review Then
Sheet1.Range(the_column & ":" & the_column).EntireColumn.Hidden = False
Else
Sheet1.Range(the_column & ":" & the_column).EntireColumn.Hidden = True
End If
Next Rep
End If
End Sub
In the module I have the following code:
Public Function GetColumnLetter_ByInteger(what_number As Integer) As String
GetColumnLetter_ByInteger = ""
MyColumn_Integer = what_number
If MyColumn_Ineger <= 26 Then
column_letter = ChrW(64 + MyColumn_Integer)
End If
If MyColumn_Integer > 26 Then
column_letter = ChrW(Int((MyColumn_Integer - 1) / 26) + 64) & ChrW(((MyColumn_Integer - 1) Mod 26) + 65)
End If
GetColumnLetter_ByInteger = column_letter
End Function
If you're asking for one sheet to detect the change in cell "A1" and then to hide/unhide columns on multiple sheets then the prior answers to your question will serve you nicely.
If, on the other hand, you're asking to detect a change in cell "A1" on any sheet and then to hide/unhide columns on just the changed sheet, then the code below will work for you. It accesses the Workbook_SheetChanged event at Workbook level.
A few points about your code:
You can reference cells using their integer or address values with the .Cell property, so Sheet1.Cells(1, 1) is the same as Sheet1.Cells(1, "A"). The same applies to the .Columns property. So there's no real need to convert your integer values to a string. See #Florent B's answer for a good example of this.
Wherever possible, minimise looping sheet interactions as these are very time-consuming. So rather than loop through the columns and hide/unhide each one individually, you could assign them to ranges within your loop and then hide/unhide the ranges all in one go at the end of your loop. If you must interact with the sheet on each iteration of your loop, then set the Application.ScreenUpdating property to false before the start of your loop. There's an example of this property in the sample code below.
Put this in your Workbook module:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Const TARGET_ADDRESS As String = "A1"
Dim cell As Range
Dim hiddenCols As Range
Dim unhiddenCols As Range
Dim selectedMonth As String
Dim monthInReview As String
Dim c As Integer
'Ignore event if not a target worksheet
If Sh.Name = "Not Wanted" Then Exit Sub
'Ignore event if not in target range
Set cell = Target.Cells(1)
If cell.Address(False, False) <> TARGET_ADDRESS Then Exit Sub
'Criteria met, so handle event
selectedMonth = CStr(cell.Value)
For c = 2 To 379
Set cell = Sh.Cells(1, c)
monthInReview = CStr(cell.Value)
'Add cell to hidden or unhidden ranges
If monthInReview = selectedMonth Then
If unhiddenCols Is Nothing Then
Set unhiddenCols = cell
Else
Set unhiddenCols = Union(unhiddenCols, cell)
End If
Else
If hiddenCols Is Nothing Then
Set hiddenCols = cell
Else
Set hiddenCols = Union(hiddenCols, cell)
End If
End If
Next
'Hide and unhide the cells
Application.ScreenUpdating = False 'not really needed here but given as example
If Not unhiddenCols Is Nothing Then
unhiddenCols.EntireColumn.Hidden = False
End If
If Not hiddenCols Is Nothing Then
hiddenCols.EntireColumn.Hidden = True
End If
Application.ScreenUpdating = True
End Sub
You can use a for each loop to loop through all the Worksheets, and check the worksheet name if it should be skipped. Then apply your code onto the sheet selected.
Something like:
Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Then
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "Skip Sheet" Then
Dim the_selection As String
Dim month_in_review As String
the_selection = ws.Range("A1")
Dim Rep As Integer
For Rep = 2 To 379
the_column = GetColumnLetter_ByInteger(Rep)
month_in_review = ws.Range(the_column & "1")
If the_selection = month_in_review Then
ws.Range(the_column & ":" & the_column).EntireColumn.Hidden = False
Else
ws.Range(the_column & ":" & the_column).EntireColumn.Hidden = True
End If
Next Rep
End If
Next ws
End If
End Sub
I wasn't entirely sure what you wished to achieve, so i put ws in the place of Sheet1.
This example will show/hide the columns in all the other sheets if the first cell of the column match/differ with the cell A1 of the sheet where this code is placed:
Private Sub Worksheet_Change(ByVal Target As Range)
' exit if not cell A1
If Target.row <> 1 Or Target.column <> 1 Then Exit Sub
Dim sheet As Worksheet
Dim the_selection As String
Dim month_in_review As String
Dim column As Integer
the_selection = Target.Value
' iterate all the sheets
For Each sheet In ThisWorkbook.Worksheets
' skip this sheet
If Not sheet Is Me Then
' iterate the columns
For column = 2 To 379
' get the first cell of the column
month_in_review = sheet.Cells(1, column).Value
' hide or show the column if it's a match or not
sheet.Columns(column).Hidden = month_in_review <> the_selection
Next
End If
Next
End Sub
I have below macro.
Could you please modify it in such ways that it will show slide number on the top and also extract notes page.
I tried all ways but couldn't get answer-:
Sub WriteToWord()
Dim aSlide As Slide, MyDoc As New Word.Document, MyRange As Word.Range
Dim aTable As Table, aShape As Shape, TablesCount As Integer, ShapesCount As Integer
Dim i As Word.Paragraph
On Error Resume Next
With MyDoc
.Application.Visible = False
.Application.ScreenUpdating = False
For Each aSlide In ActivePresentation.Slides
For Each aShape In aSlide.Shapes
Set MyRange = .Range(.Content.End - 1, .Content.End - 1)
Select Case aShape.Type
Case msoAutoShape, msoPlaceholder, msoTextBox
If aShape.TextFrame.HasText Then
aShape.TextFrame.TextRange.Copy
MyRange.Paste
With MyRange
.ParagraphFormat.Alignment = wdAlignParagraphLeft
For Each i In MyRange.Paragraphs
If i.Range.Font.Size >= 16 Then
i.Range.Font.Size = 14
Else
i.Range.Font.Size = 12
End If
Next
End With
End If
Case msoPicture
aShape.Copy
MyRange.PasteSpecial DataType:=wdPasteMetafilePicture
ShapesCount = .Shapes.Count
With .Shapes(ShapesCount)
.LockAspectRatio = msoFalse
.Width = Word.CentimetersToPoints(14)
.Height = Word.CentimetersToPoints(6)
.Left = wdShapeCenter
.ConvertToInlineShape
End With
.Content.InsertAfter Chr(13)
Case msoEmbeddedOLEObject, msoLinkedOLEObject, msoLinkedPicture, msoOLEControlObject
aShape.Copy
MyRange.PasteSpecial DataType:=wdPasteOLEObject
ShapesCount = .Shapes.Count
With .Shapes(ShapesCount)
.LockAspectRatio = msoFalse
.Width = Word.CentimetersToPoints(14)
.Height = Word.CentimetersToPoints(6)
.Left = wdShapeCenter
.ConvertToInlineShape
End With
.Content.InsertAfter Chr(13)
Case msoTable
aShape.Copy
MyRange.Paste
TablesCount = .Tables.Count
With .Tables(TablesCount)
.PreferredWidthType = wdPreferredWidthPercent
.PreferredWidth = 100
.Range.Font.Size = 11
End With
.Content.InsertAfter Chr(13)
End Select
Next
If aSlide.SlideIndex < ActivePresentation.Slides.Count Then .Content.InsertAfter Chr(12)
.UndoClear ' Clear used memory
Next
' Change white font to black color
With .Content.Find
.ClearFormatting
.Format = True
.Font.Color = wdColorWhite
.Replacement.Font.Color = wdColorAutomatic
.Execute Replace:=wdReplaceAll
End With
MsgBox "PPT Converted to WORD completed, Please check and save document", vbInformation + vbOKOnly, "ExcelHome/ShouRou"
.Application.Visible = True
.Application.ScreenUpdating = True
End With
End Sub
Sub Auto_Open() ' Add PPTtoWord to Tool Bar when Powerpoint start
Dim MyControl As CommandBarControl
On Error Resume Next
Application.CommandBars("Standard").Controls("PPTtoWord").Delete
Set MyControl = Application.CommandBars("Standard").Controls.Add(Before:=1)
With MyControl
.Caption = "PPTtoWord"
.FaceId = 567 ' Word Icon
.Enabled = True
.Visible = True
.Width = 100
.OnAction = "WriteToWord"
.Style = msoButtonIconAndCaption
End With
End Sub
Sub Auto_Close() ' Delete PPTtoWord from Tool Bar when Powerpoint close
On Error Resume Next
Application.CommandBars("Standard").Controls("PPTtoWord").Delete
End Sub
You are running this from Word and automating PowerPoint using early binding, you need to fully qualify any PowerPoint reference.
Have you added a reference to PowerPoint library.
Change to aShape As PowerPoint.Shape
Grab the reference to the running instance of PowerPoint. PowerPoint is single instance multi-use so you can use this.
Dim PPT as PowerPoint.Application
Set PPT = CreateObject("PowerPoint.Application")
Fully qualify all references to ActivePresentation with PPT.ActivePresentation
Your macro should run then and generate something so that you can continue debugging.
Sub test()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.AskToUpdateLinks = False
Dim x As Workbook
Dim y As Workbook
Set x = ActiveWorkbook
Set y = Workbooks.Open("S:\HR\Attendance Charts\2014\May 14\abc.xlsx")
y.Sheets("Report").Activate
ActiveSheet.Range("A34:DM64").Copy
x.Sheets("Modified").Activate
ActiveSheet.Range("A70").PasteSpecial xlPasteValues
y.Close
End Sub
I am using this code to copy some data from x workbook to y workbook. Size of x workbook is 13 MB and the Y is 23.5 MB. Copying the data from x and pasting it to y takes a lot of time. Is there anyway I can make this process run faster? I am using the code above. Thanks
According to http://www.ozgrid.com/VBA/SpeedingUpVBACode.htm , the following may make your code faster (it bypasses the clipboard and copies the values directly):
Sub test()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.AskToUpdateLinks = False
Dim x As Workbook
Dim y As Workbook
Dim r1 As Range ' source
Dim r2 As Range ' destination
Set x = ActiveWorkbook
Set y = Workbooks.Open("S:\HR\Attendance Charts\2014\May 14\abc.xlsx")
Set r1 = y.Sheets("Report").Range("A34:DM64")
Set r2 = x.Sheets("Modified").Range("A70:DM100")
r2.Value = r1.Value '<<<<<<<<< this is the line that does the magic
y.Close
End Sub
Do check that I set the ranges r1 and r2 correctly...
i changed Floris's code a bit, to try with a VBA Array
Sub test()
with Application
.ScreenUpdating = False
.DisplayAlerts = False
.AskToUpdateLinks = False
.enableevents=false
.calculation = Xlmanual
end with
Dim x As Workbook
Dim y As Workbook
Dim r1 As Range ' source
Dim r2 As Range ' destination
Dim Y_Array() as Variant
dim Y_Sheet as Worksheet
Dim X_Sheet as Worksheet
Set x = ActiveWorkbook
Set X_Sheet= x.Sheets("Modified") '=activesheet ' i've preferably named it with complete name here
'testing if y already opened, if it's the case win a lot of time
err.clear
on error resume next
Set y = Workbooks ("abc.xlsx")
if err<>0 then
err.clear
Set y = Workbooks.Open("S:\HR\Attendance Charts\2014\May 14\abc.xlsx")
end if
on error goto 0
with y
application.windows(.name).windowstate=xlminimized
set Y_Sheet= .Sheets("Report")
with Y_Sheet
Set r1 = .Range(.cells(34,1) , .cells(64,117) ) ' same as "A34:DM64")
with r1
redim Y_Array (1 to 30, 1 to 117) 'to make it a dynamic array : (1 to .rows.count, 1 to .columns.count)
Y_Array = .value2 'edit : modified to .value2
end with
end with
end with
Set r2 = x.Sheets("Modified").Range("A70:DM100")
r2.Value2 = Y_Array 'r1.Value '<<<<<<<<< this is the line that does the magic 'edit: modified to value2
y.Close
'Free memory
erase Y_Array
set r1=nothing
set Y_Sheet=nothing
set Y=nothing
set r2=nothing
set X_Sheet=nothing
set X=nothing
with Application
.ScreenUpdating = true 'uh, without reseting it to normal you gonna have troubles....
.DisplayAlerts = true
'.AskToUpdateLinks = true
.enableevents = true
.calculation = XlAutomatic
end with
End Sub
Code untested, not sure it really helps, give it a try...
I'm making a program in Microsoft Excel using a bunch of VB script macros.
One of my macros gets data "From Web" and retrieves the table to a sheet in excel. When I say "From Web", I just copied and pasted the URL from an html file I have on my desktop. The location of my program is going to change frequently, so I need to be able to have a cell in excel where I can specify this URL, which my macro will reference.
Here is my code below:
Sub ImportSwipeDataWithTitlesBeta()
'
' ImportSwipeDataWithTitlesBeta Macro
'
' Keyboard Shortcut: Ctrl+Shift+K
'
Sheets("Import Swipe Data").Select
Cells.Select
Selection.Delete Shift:=xlUp
Range("A3").Select
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;file:///C:/Users/Sean/Desktop/Attendance Program ADC/ACS%20OnSite%20SE%20Complete.htm", _
Destination:=Range("$A$3:$C$3"))
.Name = "ACS%20OnSite%20SE%20Complete_8"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlEntirePage
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
Sheets("Resource Sheet").Select
Range("B2:C2").Select
Selection.Copy
Sheets("Import Swipe Data").Select
Range("A1:B1").Select
ActiveSheet.Paste
Range("A2").Select
End Sub
Thanks for the Help!
You don't need to .Select every range you use. These statements are generated by recording a macro but you can clean your code afterwards as described here.
Yet, to answer your question, you can store your URL in a var:
Dim myURL As String
myURL = "URL;" & Sheets("Import Swipe Data").Range("A1").Value
With ActiveSheet.QueryTables.Add(Connection:= myURL, Destination:=Range("$A$3:$C$3"))
(...)
End With
Regards,