Trouble with custom functions (UDF) after worksheet changes

NoviceCoder

New Member
Joined
Apr 26, 2016
Messages
20
I would be really grateful for any help on a problem that I've been struggling with for some time. I am making modification to an activity tracker which has time cells across columns (D:DP) and days of the week in rows (A14:A74). Users change the cell colours to plot activity and this is detected using a custom function to summarise daily and weekly activity. This works superbly thanks to help from this forum.

Function COUNTIFCOLOUR(Colour As Range, rng As Range) As Long
Application.Volatile (True)

Dim NoCells As Long
Dim CellColour As Long
Dim rngCell As Range
CellColour = Colour.Interior.Color
For Each rngCell In rng
If rngCell.Interior.Color = CellColour Then
NoCells = NoCells + 1
End If
Next
COUNTIFCOLOUR = NoCells
End Function

The sheet is updated by code:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("D14:DQ74")) Is Nothing Then
Me.Calculate
End If
End Sub

*The problem I am having is that whenever I make changes to the sheet with VBA the summary cells (example is "=COUNTIFCOLOUR(DU15,D14:DP18)" fail to update and a green error triangle appears with hashtags. This can be resolved by going into the formula bar and pressing enter but this stops me automating the sheet in anyway. Even simple VBA code creates the same issue such as to delete a week:

Rows("14:20").Select
Selection.Delete Shift:=xlUp
Appplication.Calculate

Interestingly, if I perform the row deletion manually the UDF are okay.I've checked that calculations are set to automatic on preferences. When I run debug the toggle goes from the Delete Rows VBA code to module 1 code including the [COUNTIFCOLOUR Function] above and the formulae in summary cells error when the toggle reaches: CellColour = Colour.Interior.Color
I've even changed the Worksheet_SelectionChange to Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean) in case it was sheet changes creating the error. It makes no difference.

I am completely stumped by this. I've spent hours troubleshooting. You're my last hope ; )
 

Excel Facts

Show numbers in thousands?
Use a custom number format of #,##0,K. Each comma after the final 0 will divide the displayed number by another thousand
*The problem I am having is that whenever I make changes to the sheet with VBA the summary cells (example is "=COUNTIFCOLOUR(DU15,D14:DP18)" fail to update
Can you post the VBA code that is making these changes?
 
Upvote 0
The simple delete row via above caused the problem alone.
But what I'm trying to do is archive the first week activity and summary cells to separate archives, delete the first 7 rows and add another week to the end of the diary.the event is triggered when the date exceeds a limit in the spreadsheet.

This is the code to scroll sheet to date and decide if archive is required:

Dim daterng As Range
Dim DateCell As Range
Dim WorkSht As Worksheet
Dim DateRow As Long

Dim dateStr As String
Application.ScreenUpdating = False

Worksheets("ActivityTracker").Range("A10:A375").Select
Set daterng = Range("A:A")

For Each DateCell In daterng
DateCell.Activate
ActiveCell.Select
On Error Resume Next
dateStr = DateCell.Value
If dateStr = Date Then
DateCell.Select
DateRow = DateCell.Row
If DateRow >= 61 Then Call SendOneWeekToArchive


ActiveWindow.ScrollRow = DateRow - 10
Exit Sub
End If
Next

Application.ScreenUpdating = True
Worksheets("ActivityTracker").Select
End Sub

This is the send to archive code:

Sub SendOneWeekToArchive()

'Copy Diary record to DiaryArchive

Range("A14").Select
ActiveWindow.ScrollColumn = 65
Range("A14:DQ20").Select
Selection.Copy
Sheets("DiaryArchive").Activate
ActiveSheet.Range("A1").End(xlDown).Offset(1, 0).Activate
ActiveCell.PasteSpecial xlPasteAll



'Copy Diary Summary

Dim LastRow As Integer

Sheets("DiarySummary").Activate
ActiveSheet.Range("A1").End(xlDown).Activate
LastRow = ActiveCell.Row
LastRow = LastRow + 1

'Transpose Patient Details to Archive

Sheets("DiarySummary").Cells(LastRow, 1).Value = Sheets("ActivityTracker").Cells(14, 1).Value
Sheets("DiarySummary").Cells(LastRow, 2).Value = Sheets("ActivityTracker").Cells(14, 2).Value

Sheets("DiarySummary").Cells(LastRow, 3).Value = Sheets("ActivityTracker").Cells(15, 123).Value
Sheets("DiarySummary").Cells(LastRow, 4).Value = Sheets("ActivityTracker").Cells(15, 124).Value

Sheets("DiarySummary").Cells(LastRow, 5).Value = Sheets("ActivityTracker").Cells(16, 123).Value
Sheets("DiarySummary").Cells(LastRow, 6).Value = Sheets("ActivityTracker").Cells(16, 124).Value

Sheets("DiarySummary").Cells(LastRow, 7).Value = Sheets("ActivityTracker").Cells(17, 123).Value
Sheets("DiarySummary").Cells(LastRow, 8).Value = Sheets("ActivityTracker").Cells(17, 124).Value

Sheets("DiarySummary").Cells(LastRow, 9).Value = Sheets("ActivityTracker").Cells(18, 123).Value
Sheets("DiarySummary").Cells(LastRow, 10).Value = Sheets("ActivityTracker").Cells(18, 124).Value

' Next Set of Summaries

Sheets("DiarySummary").Cells(LastRow, 11).Value = Sheets("ActivityTracker").Cells(15, 129).Value
Sheets("DiarySummary").Cells(LastRow, 12).Value = Sheets("ActivityTracker").Cells(15, 130).Value

Sheets("DiarySummary").Cells(LastRow, 13).Value = Sheets("ActivityTracker").Cells(16, 129).Value
Sheets("DiarySummary").Cells(LastRow, 14).Value = Sheets("ActivityTracker").Cells(16, 130).Value

Sheets("DiarySummary").Cells(LastRow, 15).Value = Sheets("ActivityTracker").Cells(17, 129).Value
Sheets("DiarySummary").Cells(LastRow, 16).Value = Sheets("ActivityTracker").Cells(17, 130).Value

Sheets("DiarySummary").Cells(LastRow, 17).Value = Sheets("ActivityTracker").Cells(18, 129).Value
Sheets("DiarySummary").Cells(LastRow, 18).Value = Sheets("ActivityTracker").Cells(18, 130).Value

'Final set of Summaries

Sheets("DiarySummary").Cells(LastRow, 19).Value = Sheets("ActivityTracker").Cells(15, 135).Value
Sheets("DiarySummary").Cells(LastRow, 20).Value = Sheets("ActivityTracker").Cells(15, 136).Value

Sheets("DiarySummary").Cells(LastRow, 21).Value = Sheets("ActivityTracker").Cells(16, 135).Value
Sheets("DiarySummary").Cells(LastRow, 22).Value = Sheets("ActivityTracker").Cells(16, 136).Value

Sheets("DiarySummary").Cells(LastRow, 23).Value = Sheets("ActivityTracker").Cells(17, 135).Value
Sheets("DiarySummary").Cells(LastRow, 24).Value = Sheets("ActivityTracker").Cells(17, 136).Value

Sheets("DiarySummary").Cells(LastRow, 25).Value = Sheets("ActivityTracker").Cells(18, 135).Value
Sheets("DiarySummary").Cells(LastRow, 26).Value = Sheets("ActivityTracker").Cells(18, 136).Value


Sheets("ActivityTracker").Activate
Rows("14:20").Select
Selection.Delete Shift:=xlUp





''Add empty week to end of activitytracker

Sheets("TemplateWeek").Activate
Range("B1").Select
ActiveWindow.ScrollColumn = 105
Range("A1:EH7").Select
Application.CutCopyMode = False
Selection.Copy

Sheets("ActivityTracker").Activate
ActiveSheet.Range("A14").End(xlDown).Offset(1, 0).Activate
Dim NewDateCell As Integer
Dim LastDateCell As Integer
Dim FinalDateCell As Integer

NewDateCell = ActiveCell.Row
LastDateCell = NewDateCell - 1
FinalDateCell = NewDateCell + 6

ActiveCell.PasteSpecial xlPasteAll

Set srcRange = ActiveSheet.Range("A" & LastDateCell) '
Set destRange = ActiveSheet.Range(Cells(LastDateCell, 1), Cells(FinalDateCell, 1)) '
srcRange.AutoFill destRange, xlFillSeries 'xlFillSeries will auto fill the dates in sequence

'Correct scroll position after archiving variable should be defined in editor at work book opening

DateRow = DateRow - 7

End Sub
 
Upvote 0
have you tried changing
VBA Code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("D14:DQ74")) Is Nothing Then
Me.Calculate
End If
End Sub
to
VBA Code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("D14:DQ74")) Is Nothing Then
Application.CalculateFull
End If
End Sub
 
Upvote 0
Solution
Thanks. I have tried that and it doesn't work.
When the short delete vba runs then it executes the deletion of 7 rows then it runs into the following code:
Function COUNTIFCOLOUR(Colour As Range, rng As Range) As Long
Application.Volatile (True)

Dim NoCells As Long
Dim CellColour As Long
Dim rngCell As Range
CellColour = Colour.Interior.Color

It is on this last line that the error seems to occur. At this point an area is selected (7 rows) which includes the intersect area for sheet change and cells beyond that. I though it was something to do with multiple cells still being selected but when i inserted code to select a single cell A12 then the error still occurred.
 
Upvote 0
Thanks for the advice
The problem has been solved
maybe the Application. CalculateFull helped but i still cant get it to work on excel for mac
used the same code on my PC and it works perfectly albeit a bit slowly
Thank you
 
Upvote 0
This shows the danger of using color as variable, excel is very slow at dealing with any format, so checking or setting colors is very slow. I believe that well designed system should always store information as values in cells never as a color or any other formatting. This would mean yu never have to count colors!! Formatting should only be used to help humans look at the results.
 
Upvote 0
I agree with you. I think the users are just entrenched in using colours. I did think about implementing conditional formatting to change cell colours once numbers are entered. But I think they're used to selecting a block of cells and clicking a colour. I am not sure if there is a way of replicating that functionality. Let me know if some one smarter than me figures out how to do it.
 
Upvote 0

Forum statistics

Threads
1,214,838
Messages
6,121,885
Members
449,057
Latest member
Moo4247

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top