Excel quits on Worksheet_Change Event - vba

Can someone please point out what's wrong with this snippet of code? Every time a value is changed in the specified range (A1:B6), Excel simply quits with Microsoft Error Reporting dialogue. I am not allowed to uncheck 'Error Checking (Turn on background error checking)' in Excel Preferences.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Set KeyCells = Range("A1:B6")
If Not Application.Intersect(KeyCells, Range(Target.Address)) Is Nothing Then
Call Macro1
MsgBox "Test"
End If
End Sub
Macro1:
Sub Macro1()
Dim wb As Workbook
Dim wsData As Worksheet
Dim wsDest As Worksheet
Dim rInterestCell As Range
Dim rDest As Range
Set wb = ActiveWorkbook
Set wsData = wb.Sheets("Sheet1")
Set wsDest = wb.Sheets("Formula Results")
For Each rInterestCell In Range("Interest_Range").Cells
wsData.Range("A7").Value = rInterestCell.Value
wsData.Calculate
Set rDest = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Offset(1)
If rDest.Row < 6 Then Set rDest = wsDest.Range("A6")
rDest.Value = wsData.Range("A6").Value
Next rInterestCell
End Sub
Second Macro
Sub Macro2()
Dim FLrange As Range
Set FLrange = Range(“Initial_Rate”)
For Each cell In FLrange
cell.Offset(0, 5).Formula = "=SUM(B3/100*A7)”
Next cell
End Sub

You'd better turn off events with Application.EnableEvents = False before doing so much calculation in Macro1.
If this works, just comment MsgBox "Before Macro1" and MsgBox "After Macro1"
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Set KeyCells = Me.Range("A1:B6")
If Not Application.Intersect(KeyCells, Target) Is Nothing Then
MsgBox "Before Macro1"
Macro1
MsgBox "After Macro1"
End If
End Sub
Macro1:
Sub Macro1()
Dim wB As Workbook
Dim wsData As Worksheet
Dim wsDest As Worksheet
Dim rInterestCell As Range
Dim rDest As Range
Set wB = ActiveWorkbook
Set wsData = wB.Sheets("Sheet1")
Set wsDest = wB.Sheets("Formula Results")
Application.EnableEvents = False
For Each rInterestCell In Range("Interest_Range").Cells
wsData.Range("A7").Value = rInterestCell.Value
wsData.Calculate
DoEvents
Set rDest = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Offset(1)
If rDest.Row < 6 Then Set rDest = wsDest.Range("A6")
rDest.Value = wsData.Range("A6").Value
Next rInterestCell
Application.EnableEvents = True
End Sub

Related

Embed Chart Template into Macro

I am trying to embed applying a chart template into a macro and require help.
I have this code for the Macro that I am using to create scatter plots:
Option Explicit
Public Sub Test()
' Keyboard Shortcut: Ctrl+Shift+X
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Sheet1") 'change as appropriate
Application.ScreenUpdating = False
BuildChart ws, SelectRanges(ws)
Application.ScreenUpdating = True
End Sub
Private Function SelectRanges(ByRef ws As Worksheet) As Range
Dim rngX As Range
Dim rngY As Range
ws.Activate
Application.DisplayAlerts = False
On Error Resume Next
Set rngX = Application.InputBox("Please select X values. One column.",
Type:=8)
If rngX Is Nothing Then GoTo InvalidSelection
Set rngY = Application.InputBox("Please select Y values. One column.",
Type:=8)
If rngY Is Nothing Then GoTo InvalidSelection
If rngX.Columns.Count > 1 Or rngY.Columns.Count > 1 Then GoTo
InvalidSelection
On Error GoTo 0
Set SelectRanges = Union(rngX, rngY)
Application.DisplayAlerts = True
Exit Function
InvalidSelection:
If rngX Is Nothing Or rngY Is Nothing Then
MsgBox "Please ensure you have selected both X and Y ranges."
ElseIf rngX.Rows.Count <> rngX.Rows.Count Then
MsgBox "Please ensure the same number of rows are selected for X and Y
ranges"
ElseIf rngX.Columns.Count > 1 Or rngY.Columns.Count > 1 Then
MsgBox "Please ensure X range has only one column and Y range has only
one column"
Else
MsgBox "Unspecified"
End If
Application.DisplayAlerts = True
End
End Function
Private Sub BuildChart(ByRef ws As Worksheet, ByRef unionRng As Range)
With ws.Shapes.AddChart2(240, xlXYScatter).Chart
.SetSourceData Source:=unionRng
End With
ActiveChart.ApplyChartTemplate ( _
"C:\Users\maaro\AppData\Roaming\Microsoft\Templates\Charts\1.crtx")
End Sub
And would like to embed this code below into the above code so that it applies the template to the chart I create whenever I run this Macro. My initial guess would be to put it underneath "Private Sub BuildCharts". How would I be able to do this? Thank you.
ActiveChart.ApplyChartTemplate ( _
"C:\Users\XXXXX\AppData\Roaming\Microsoft\Templates\Charts\1.crtx")
Perhaps modify Sub BuildChart like this:
Private Sub BuildChart(ByRef ws As Worksheet, ByRef unionRng As Range)
With ws.Shapes.AddChart2(240, xlXYScatter).Chart
.SetSourceData Source:=unionRng
.ApplyChartTemplate ( _
"C:\Users\maaro\AppData\Roaming\Microsoft\Templates\Charts\1.crtx")
End With
End Sub

Counting cells of worksheets within another workbook

I have one xlsm file with a single button in it which, when clicked, is supposed to open a separate workbook and search through all contained worksheets for cells of a specific colour.
The problem is, instead of searching the other workbook's worksheets, it just searches itself. I'm new to VBA, and feel like i've been round the internet 6 times trying to solve this. What am I doing wrong here?
Private Sub CommandButton1_Click()
Dim wb As Workbook
Dim ws As Worksheet
Dim holdCount As Integer
Dim cellColour As Long
Dim cell As Range, rng As Range
Set wb = Workbooks.Open("blahblahblah.xls")
Set rng = Range("A1:A20")
holdCount = 0
cellColour = RGB(255, 153, 0)
For Each ws In wb.Worksheets
For Each cell In rng
If cell.Interior.Color = cellColour Then
holdCount = holdCount + 1
End If
Next cell
Next ws
MsgBox "found " & holdCount
End Sub
It looks to me like you aren't fully qualifying your Range
Move this inside of your ws loop instead of where it is now.
Set rng = ws.Range("A1:A20")
BraX pointed out that I needed to qualify the Range WITHIN the For Each ws loop, so here is the fixed and working code. Again, all credit to Brax.
Private Sub CommandButton1_Click()
Dim wb As Workbook
Dim ws As Worksheet
Dim holdCount As Integer
Dim cellColour As Long
Dim cell As Range, rng As Range
Set wb = Workbooks.Open("blahblahblah.xls")
holdCount = 0
cellColour = RGB(255, 153, 0)
For Each ws In wb.Worksheets
With ws
Set rng = ws.Range("A1:A20")
For Each cell In rng
If cell.Interior.Color = cellColour Then
holdCount = holdCount + 1
End If
Next cell
End With
Next ws
MsgBox "found " & holdCount
End Sub

excel sheet creation and update

I am looking for a way to create sheets in excel based on a list of cells
problem I have is that I would like the script to check if the list was updated and add the additional sheets and not re create all or delete the old copies
1) is it possible from excel (non VBA)
2) if not the code i have for creating a sheet is :
but it will create new entrys if I re-run (and I am looking for update)
Sub AddSheets()
'Updateby Extendoffice 20161215
Dim xRg As Excel.Range
Dim wSh As Excel.Worksheet
Dim wBk As Excel.Workbook
Set wSh = ActiveSheet
Set wBk = ActiveWorkbook
Application.ScreenUpdating = False
For Each xRg In wSh.Range("A1:A7")
With wBk
.Sheets.Add after:=.Sheets(.Sheets.Count)
On Error Resume Next
ActiveSheet.Name = xRg.Value
If Err.Number = 1004 Then
Debug.Print xRg.Value & " already used as a sheet name"
End If
On Error GoTo 0
End With
Next xRg
Application.ScreenUpdating = True
End Sub
Here's another option. I also added a part where it'll name the sheet the column A value. (You can remove that if needed).
Sub AddSheets()
'Updateby Extendoffice 20161215
Dim xRg As Excel.Range
Dim wSh As Excel.Worksheet
Dim wBk As Excel.Workbook
Set wSh = ActiveSheet
Set wBk = ActiveWorkbook
Application.ScreenUpdating = False
For Each xRg In wSh.Range("A1:A7")
With wBk
If Not sheetExists(xRg.Value) and xRg <> "" Then
.Sheets.Add after:=.Sheets(.Sheets.Count)
ActiveSheet.Name = xRg.Value
End If
End With
Next xRg
Application.ScreenUpdating = True
End Sub
Function sheetExists(sheetToFind As String) As Boolean
'http://stackoverflow.com/a/6040454/4650297
Dim sheet As Worksheet
sheetExists = False
For Each sheet In Worksheets
If sheetToFind = sheet.Name Then
sheetExists = True
Exit Function
End If
Next sheet
End Function
Use this function to check if the worksheet already exists, then let it skip over it.
Function WorksheetExists(sName As String) As Boolean
WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function
So your code can be:
Sub AddSheets()
'Updateby Extendoffice 20161215
Dim xRg As Variant
Dim wSh As Excel.Worksheet
Dim wBk As Excel.Workbook
Set wSh = ActiveSheet
Set wBk = ActiveWorkbook
Application.ScreenUpdating = False
For Each xRg In wSh.Range("A1:A7")
If Not IsError(xRg) Then
If xRg <> "" Then
If Not WorkSheetExists((xRg)) Then
With wBk
.Sheets.Add after:=.Sheets(.Sheets.Count)
ActiveSheet.Name = xRg.Value
End With
End If
End If
End If
Next xRg
Application.ScreenUpdating = True
End Sub
Function WorksheetExists(sName As String) As Boolean
WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function

Copy and paste from other workbook

Im trying to copy all the cells that contain blue font and copy in another workbook in the same range of the source, but im lost at this point. Everytime that i try to run this code, i get an run-time error.
Sub test2()
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlManual
Dim FonteA As Workbook, FonteB As Workbook
Dim ws As Worksheet
Dim vFile As Variant
Dim rCell As Range
Dim lColor As Long
Dim rColored As Range
'Set source workbook
Set FonteB = ActiveWorkbook
'Open the target workbook
vFile = Application.GetOpenFilename
'if the user didn't select a file, exit sub
If TypeName(vFile) = "Boolean" Then Exit Sub
Workbooks.Open vFile
'Set targetworkbook
Set FonteA = ActiveWorkbook
FonteB.Worksheets("USD - SCHEDULE A").Activate
lColor = RGB(0, 0, 255)
Cells.CurrentRegion.Select
Set rColored = Nothing
For Each rCell In Selection
If rCell.Font.Color = lColor Then
If rColored Is Nothing Then
Set rColored = rCell
Else
Set rColored = Union(rColored, rCell)
End If
End If
Next
If rColored Is Nothing Then
MsgBox "No cells match the color"
Else
rColored.Select
rColored.Copy
End If
Set rCell = Nothing
Set rColored = Nothing
FonteA.Worksheets("Matriz_Produto").PasteSpecial Paste:=xlPasteFormats
FonteA.Worksheets("Matriz_Produto").PasteSpecial Paste:=xlPasteValues
Application.Calculation = xlAutomatic
End Sub
No idea where that specific error is coming from (it looks like it should actually be an error 1004), but I'm guessing just switching from using Activate and Select will resolve it. Try the following:
'Set source workbook
Set FonteB = ActiveWorkbook
'Open the target workbook
vFile = Application.GetOpenFilename
'if the user didn't select a file, exit sub
If TypeName(vFile) = "Boolean" Then Exit Sub
'Set targetworkbook
Set FonteA = Workbooks.Open(vFile)
Dim ws As Worksheet
Set ws = FonteB.Worksheets("USD - SCHEDULE A")
lColor = RGB(0, 0, 255)
For Each rCell In ws.Cells.CurrentRegion
If rCell.Font.Color = lColor Then
If rColored Is Nothing Then
Set rColored = rCell
Else
Set rColored = Union(rColored, rCell)
End If
End If
Next

Display message when cell is empty

Currently I managed to do for a single cell when the specified cell is empty then message / statement display on the cell.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("AA17").Value = ISBLANK Then
Range("AA17").Value = "Please Specify"
End If
End Sub
What I would like to do is, for a several cell it will display the same thing. I can go ahead and do the same as above for all celsl but I have a few hundred cell to format it that way.
Is there a way to do so?
If the cells are contiguous, you could loop through them.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim checkRng As Range
Dim cel As Range
Set checkRng = Range("A7:A70")
For Each cel In checkRng
If cel.Value = ISBLANK Then
cel.Value = "Please Specify"
End If
Next cel
End Sub
if there is any changes within the specified Range, the below code will run
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim Rng As Range
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.ActiveSheet
Set Rng = ws.Range("A1:A100")
If Not Intersect(Target, Rng) Is Nothing Then
For Each Cell In Rng
If IsEmpty(Cell.Value) = True Then
Cell.Value = "Please Specify"
End If
Next
End If
Set Rng = Nothing
Set ws = Nothing
Set wb = Nothing
End Sub