Advertisement
NativeUnamerican

VBA Excel Range Comparison Macro

Sep 20th, 2024 (edited)
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VisualBasic 18.05 KB | Source Code | 0 0
  1. 'Use this VBA Excel macro to quickly compare two ranges and highlight differences on a new unsaved workbook.
  2.  
  3. 'To use, open a new workbook and save as macro enabled workbook. Enable macro settings. Get into the code editor with Alt+F11 and go to Tools > References. Make sure Microsoft Scripting Runtime is checked. Under project explorer, go to modules > insert twice: Module1 and Module2. Copy the MODULE1 code below to Module1 and MODULE2 > Module2. Close VB editor and open some file(s) you want to compare. Open macros (alt+f8) and run the Compare2Ranges macro and follow the prompts. First select an entire range with headers as range1. Then select at least one header key cell (or more) like a person's name or account number, or both, for example. Then optionally select any headers for which you want the tool to ignore changes. Now repeat these three steps with range2 and viola!
  4.  
  5. 'MODULE1 - PRIMARY ROUTINE
  6.  
  7. Option Explicit
  8.  
  9. Sub Compare2Ranges()
  10.  
  11. '//DECLARE VARIABLES
  12. Dim dictrng1 As Object, dictrng2 As Object, dictCombinedHdrs_HdrNm_pField As Object, dictCombinedHdrs_pField_HdrNm As Object
  13. Dim dictIgnoreHdr1 As Object, dictIgnoreHdr2 As Object, dictIgnoreHdr As Object, tempDict As Object, dictRecord As Object
  14. Dim rng1 As Range, rng1Keys As Range, rng1Ignore As Range
  15. Dim rng2 As Range, rng2Keys As Range, rng2Ignore As Range
  16. Dim arr As Variant, arr2 As Variant
  17. Dim b As Byte, b2 As Byte, numFields As Byte
  18. Dim i As Long, i2 As Long, askToIgnore As Long
  19. Dim c As Range
  20. Dim key As Variant, pVal As Variant, pVal2 As Variant
  21. Dim pName As String, uniqueKey As String, thisKey As String, hdrOut As String
  22. Dim newBk As Workbook
  23. Dim ws As Worksheet
  24. Dim allBlank As Boolean
  25.  
  26. '//INITIAL VARIABLES AND SETTINGS
  27. '/INTIALIZE DICTIONARIES
  28. Set dictrng1 = New Scripting.Dictionary
  29. Set dictrng2 = New Scripting.Dictionary
  30. Set dictCombinedHdrs_HdrNm_pField = New Scripting.Dictionary
  31. Set dictCombinedHdrs_pField_HdrNm = New Scripting.Dictionary
  32. Set dictIgnoreHdr1 = New Scripting.Dictionary
  33. Set dictIgnoreHdr2 = New Scripting.Dictionary
  34. Set dictIgnoreHdr = New Scripting.Dictionary
  35.  
  36. '/GET 2 RANGES, KEY COLS AND IGNORE COLS FROM USER
  37. On Error Resume Next
  38. If ThisWorkbook.Worksheets("Sheet1").Range("L4") = False _
  39. Or ThisWorkbook.Worksheets("Sheet1").Range("L4") = "" Then
  40.     Set rng1 = Application.InputBox(prompt:="Select first range w/ headers", Title:="Set Range 1", Type:=8)
  41.     If rng1 Is Nothing Then GoTo skipdown
  42.     rng1.Parent.Activate
  43.     Set rng1Keys = Application.InputBox(prompt:="Select unique key fields - select header cell(s)", Title:="Set Keys - Range 1", Type:=8)
  44.     If rng1Keys Is Nothing Then GoTo skipdown
  45.     Set rng1Ignore = Application.InputBox(prompt:="Select fields to ignore - select header cell(s) or cancel", Title:="Set Ignores - Range 1", Type:=8)
  46.     Set rng2 = Application.InputBox(prompt:="Select second range w/ headers", Title:="Set Range 2", Type:=8)
  47.     If rng2 Is Nothing Then GoTo skipdown
  48.     rng2.Parent.Activate
  49.     Set rng2Keys = Application.InputBox(prompt:="Select unique key fields - select header cell(s)", Title:="Set Keys - Range 2", Type:=8)
  50.     If rng2Keys Is Nothing Then GoTo skipdown
  51.     Set rng2Ignore = Application.InputBox(prompt:="Select fields to ignore - select headers cell(s) or cancel", Title:="Set Ignores - Range 2", Type:=8)
  52. Else
  53.     'Default ranges
  54.    Set rng1 = ActiveWorkbook.Sheets("Aug").Range("A1:L1525")
  55.     rng1.Parent.Activate
  56.     'Set rng1Keys = ActiveWorkbook.Sheets("Aug").Range("B1,L1")
  57.    Set rng1Keys = ActiveWorkbook.Sheets("Aug").Range("B1,K1")
  58.     'Set rng1Ignore = ActiveWorkbook.Sheets("Aug").Range("E1,J1,K1")
  59.    Set rng1Ignore = ActiveWorkbook.Sheets("Aug").Range("I1,J1")
  60.    
  61.     Set rng2 = ActiveWorkbook.Sheets("Sep").Range("A1:K1527")
  62.     rng2.Parent.Activate
  63.     Set rng2Keys = ActiveWorkbook.Sheets("Sep").Range("B1,K1")
  64.     Set rng2Ignore = ActiveWorkbook.Sheets("Sep").Range("I1,J1")
  65. End If
  66. On Error GoTo 0
  67.  
  68. '/ENVIRONMENT SETTINGS
  69. Optimize True
  70.  
  71. '//MAIN CODE
  72. '/IMPORT RANGES TO ARRAYS - IGNORE EMPTY COLS
  73. arr = rng1
  74. ReDim tempArr(LBound(arr, 1) To UBound(arr, 1), 1 To 1)
  75. b2 = 1
  76. For b = LBound(arr, 2) To UBound(arr, 2)
  77.     If Not IsColumnBlank(arr, b) Then
  78.         ReDim Preserve tempArr(LBound(arr, 1) To UBound(arr, 1), 1 To b2)
  79.         For i = LBound(arr, 1) To UBound(arr, 1)
  80.             tempArr(i, b2) = arr(i, b)
  81.         Next i
  82.         b2 = b2 + 1
  83.     End If
  84. Next b
  85. arr = tempArr
  86. arr2 = rng2
  87. ReDim tempArr(LBound(arr2, 1) To UBound(arr2, 1), 1 To 1)
  88. b2 = 1
  89. For b = LBound(arr2, 2) To UBound(arr2, 2)
  90.     If Not IsColumnBlank(arr2, b) Then
  91.         ReDim Preserve tempArr(LBound(arr2, 1) To UBound(arr2, 1), 1 To b2)
  92.         For i = LBound(arr2, 1) To UBound(arr2, 1)
  93.             tempArr(i, b2) = arr2(i, b)
  94.         Next i
  95.         b2 = b2 + 1
  96.     End If
  97. Next b
  98. arr2 = tempArr
  99. Erase tempArr
  100.  
  101.  
  102. '/ADD ARRAYS TO DICTIONARIES
  103. '>Add rng1 and rng2 records to dicts via recordClass class
  104. '>keys=specified cols in rng1&2b, vals=record object
  105.  
  106. '>Ignorable fields dicts - step 1: add fields specified by user
  107. '>dictIgnoreHdr1=Col_Name|1
  108. If Not rng1Ignore Is Nothing Then
  109. For Each c In rng1Ignore
  110.     If Not dictIgnoreHdr1.Exists(c.value) Then
  111.         dictIgnoreHdr1.Add c.value, 1
  112.     End If
  113. Next c
  114. End If
  115. '>dictIgnoreHdr2=Col_Name|1
  116. If Not rng2Ignore Is Nothing Then
  117. For Each c In rng2Ignore
  118.     If Not dictIgnoreHdr2.Exists(c.value) Then
  119.         dictIgnoreHdr2.Add c.value, 1
  120.     End If
  121. Next c
  122. End If
  123.  
  124. '>Combined header dict - step 1: gather headers and track whether in just rng1 (1), just rng2 (2) or both (3)
  125. '>dictCombinedHdrs_HdrNm_pField=Col_Name|1, 2 or 3
  126. For b = LBound(arr, 2) To UBound(arr, 2)
  127.     If Not dictCombinedHdrs_HdrNm_pField.Exists(arr(1, b)) Then
  128.         dictCombinedHdrs_HdrNm_pField.Add arr(1, b), 1
  129.     End If
  130. Next b
  131. For b = LBound(arr2, 2) To UBound(arr2, 2)
  132.     If Not dictCombinedHdrs_HdrNm_pField.Exists(arr2(1, b)) Then
  133.         dictCombinedHdrs_HdrNm_pField.Add arr2(1, b), 2
  134.     Else
  135.         dictCombinedHdrs_HdrNm_pField(arr2(1, b)) = 3
  136.     End If
  137. Next b
  138.  
  139. '>Combined header dict - step 2: if there are any header diffs ask user if they want to ignore and add to ignore dicts
  140. '>then change combined header vals to pField#
  141. '>dictCombinedHdrs_HdrNm_pField=Col_Name|pField#
  142. numFields = dictCombinedHdrs_HdrNm_pField.Count
  143. b = 1
  144. For Each key In dictCombinedHdrs_HdrNm_pField.Keys
  145.     If dictCombinedHdrs_HdrNm_pField(key) = 1 Then
  146.         If Not dictIgnoreHdr1.Exists(key) Then
  147.             askToIgnore = MsgBox(prompt:="Header '" & key & "' found only in first range. Do you want to " _
  148.                 & "ignore this column for purposes of identifying differences (choose 'YES' or 'NO'). If 'NO' then every record " _
  149.                 & "will be flagged as having a difference and written to final report.", Buttons:=vbYesNo, Title:="Warning")
  150.             If askToIgnore = vbYes Then dictIgnoreHdr1.Add key, 1
  151.         End If
  152.     ElseIf dictCombinedHdrs_HdrNm_pField(key) = 2 Then
  153.         If Not dictIgnoreHdr2.Exists(key) Then
  154.             askToIgnore = MsgBox(prompt:="Header '" & key & "' found only in second range. Do you want to " _
  155.                 & "ignore this column for purposes of identifying differences (choose 'YES' or 'NO'). If 'NO' then every record " _
  156.                 & "will be flagged as having a difference and written to final report.", Buttons:=vbYesNo, Title:="Warning")
  157.             If askToIgnore = vbYes Then dictIgnoreHdr2.Add key, 1
  158.         End If
  159.     End If
  160.     dictCombinedHdrs_HdrNm_pField(key) = "pField" & b
  161.     b = b + 1
  162. Next key
  163.  
  164. '>Build inverse combined header dict
  165. '>dictCombinedHdrs_pField_HdrNm=pField#|Col_Name)
  166. For Each key In dictCombinedHdrs_HdrNm_pField.Keys
  167.     dictCombinedHdrs_pField_HdrNm.Add dictCombinedHdrs_HdrNm_pField(key), key
  168. Next key
  169.  
  170. '>Ignorable fields dicts - step 2: update keys to pField#
  171. '>dictIgnoreHdr#=pField#|1
  172. Set tempDict = dictIgnoreHdr1
  173. Set dictIgnoreHdr1 = New Scripting.Dictionary
  174. For Each key In tempDict
  175.     If Not dictIgnoreHdr1.Exists(dictCombinedHdrs_HdrNm_pField(key)) Then
  176.         dictIgnoreHdr1.Add dictCombinedHdrs_HdrNm_pField(key), 1
  177.     End If
  178.     If Not dictIgnoreHdr.Exists(dictCombinedHdrs_HdrNm_pField(key)) Then
  179.         dictIgnoreHdr.Add dictCombinedHdrs_HdrNm_pField(key), 1
  180.     End If
  181. Next key
  182. Set tempDict = dictIgnoreHdr2
  183. Set dictIgnoreHdr2 = New Scripting.Dictionary
  184. For Each key In tempDict
  185.     If Not dictIgnoreHdr2.Exists(dictCombinedHdrs_HdrNm_pField(key)) Then
  186.         dictIgnoreHdr2.Add dictCombinedHdrs_HdrNm_pField(key), 1
  187.     End If
  188.     If Not dictIgnoreHdr.Exists(dictCombinedHdrs_HdrNm_pField(key)) Then
  189.         dictIgnoreHdr.Add dictCombinedHdrs_HdrNm_pField(key), 1
  190.     End If
  191. Next key
  192. Set tempDict = Nothing
  193.  
  194. 'Fill dictrng1 with records
  195. For i = LBound(arr, 1) + 1 To UBound(arr, 1)
  196.     Set dictRecord = New Scripting.Dictionary
  197.     allBlank = True
  198.     For b = LBound(arr, 2) To UBound(arr, 2)
  199.         pName = dictCombinedHdrs_HdrNm_pField(arr(1, b))
  200.         pVal = CVar(arr(i, b))
  201.         If allBlank = True Then
  202.             If pVal <> "" Then
  203.                 allBlank = False
  204.             End If
  205.         End If
  206.         dictRecord.Add pName, pVal
  207.     Next b
  208.     If allBlank = False Then
  209.         uniqueKey = ""
  210.         For Each c In rng1Keys
  211.             If dictRecord.Exists(dictCombinedHdrs_HdrNm_pField(c.value)) Then
  212.                 thisKey = dictRecord(dictCombinedHdrs_HdrNm_pField(c.value))
  213.             Else
  214.                 MsgBox "error"
  215.             End If
  216.             uniqueKey = uniqueKey & thisKey
  217.         Next c
  218.         uniqueKey = GetUniqueKey(dictrng1, uniqueKey)
  219.         If Not dictrng1.Exists(uniqueKey) Then
  220.             dictrng1.Add uniqueKey, dictRecord
  221.         Else
  222.             MsgBox "Error - duplicate keys"
  223.         End If
  224.     End If
  225. Next i
  226.  
  227. 'Fill dictrng2 with records
  228. For i = LBound(arr2, 1) + 1 To UBound(arr2, 1)
  229.     Set dictRecord = New Scripting.Dictionary
  230.     allBlank = True
  231.     For b = LBound(arr2, 2) To UBound(arr2, 2)
  232.         pName = dictCombinedHdrs_HdrNm_pField(arr2(1, b))
  233.         pVal = CVar(arr2(i, b))
  234.         If allBlank = True Then
  235.             If pVal <> "" Then
  236.                 allBlank = False
  237.             End If
  238.         End If
  239.         dictRecord.Add pName, pVal
  240.     Next b
  241.     If allBlank = False Then
  242.         uniqueKey = ""
  243.         For Each c In rng2Keys
  244.             If dictRecord.Exists(dictCombinedHdrs_HdrNm_pField(c.value)) Then
  245.                 thisKey = dictRecord(dictCombinedHdrs_HdrNm_pField(c.value))
  246.             Else
  247.                 MsgBox "error"
  248.             End If
  249.             uniqueKey = uniqueKey & thisKey
  250.         Next c
  251.         uniqueKey = GetUniqueKey(dictrng2, uniqueKey)
  252.         If Not dictrng2.Exists(uniqueKey) Then
  253.             dictrng2.Add uniqueKey, dictRecord
  254.         Else
  255.             MsgBox "Error - duplicate keys"
  256.         End If
  257.     End If
  258. Next i
  259.  
  260. 'Write record differences to arr1 (vals) and formats to arr2 (0 = reg, 0.1 = reg/comma # format, 1 = Bold, 1.1 = bold/charcoal, 2 = yellow, 2.1 yellow/comma)
  261. ReDim arr(1 To UBound(arr, 1) + UBound(arr2, 1) + 10, 1 To numFields + 2)
  262. arr2 = arr
  263.  
  264. '>Header
  265. arr(1, 1) = "Rng"
  266. arr2(1, 1) = 1
  267. arr(1, 2) = "Key"
  268. arr2(1, 2) = 1
  269. For b = 1 To numFields
  270.     If dictCombinedHdrs_pField_HdrNm.Exists("pField" & b) Then
  271.         hdrOut = dictCombinedHdrs_pField_HdrNm("pField" & b)
  272.     Else
  273.         hdrOut = "pField" & b
  274.     End If
  275.     arr(1, b + 2) = hdrOut
  276.     If Not dictIgnoreHdr.Exists("pField" & b) Then
  277.         arr2(1, b + 2) = 1
  278.     Else
  279.         arr2(1, b + 2) = 1.1
  280.     End If
  281. Next b
  282.  
  283. '>Diffs: in rng1 not rng2
  284. i = 1
  285. i2 = 0
  286. For Each key In dictrng1.Keys
  287.     If Not dictrng2.Exists(key) Then
  288.         If i2 = 0 Then
  289.             i = i + 1
  290.             arr(i, 1) = "Records in range1 only"
  291.             arr2(i, 1) = 1
  292.             i = i + 1
  293.             i2 = 1
  294.         End If
  295.         arr(i, 1) = "Rng1"
  296.         arr(i, 2) = "'" & key
  297.         For b = 1 To numFields
  298.             pName = "pField" & b
  299.             If dictrng1(key).Exists(pName) Then
  300.                 pVal = dictrng1(key)(pName)
  301.             Else
  302.                 pVal = ""
  303.             End If
  304.             arr(i, b + 2) = pVal
  305.         Next b
  306.         i = i + 1
  307.     End If
  308. Next key
  309.  
  310. '>Diffs: in rng2 not rng1
  311. i2 = 0
  312. For Each key In dictrng2.Keys
  313.     If Not dictrng1.Exists(key) Then
  314.         If i2 = 0 Then
  315.             i = i + 1
  316.             arr(i, 1) = "Records in range2 only"
  317.             arr2(i, 1) = 1
  318.             i = i + 1
  319.             i2 = 1
  320.         End If
  321.         arr(i, 1) = "Rng2"
  322.         arr(i, 2) = "'" & key
  323.         For b = 1 To numFields
  324.             pName = "pField" & b
  325.             If dictrng2(key).Exists(pName) Then
  326.                 pVal = dictrng2(key)(pName)
  327.             Else
  328.                 pVal = ""
  329.             End If
  330.             arr(i, b + 2) = pVal
  331.         Next b
  332.         i = i + 1
  333.     End If
  334. Next key
  335.  
  336. '>Changes
  337. i = i + 1
  338. i2 = i
  339. arr(i, 1) = "Changes"
  340. arr2(i, 1) = 1
  341. i = i + 1
  342. For Each key In dictrng1.Keys
  343.     If dictrng2.Exists(key) Then
  344.         If Not IsEqual(dictrng1(key), dictrng2(key), dictIgnoreHdr) Then
  345.             arr(i, 1) = "Rng1"
  346.             arr(i, 2) = "'" & key
  347.             For b = 1 To numFields
  348.                 pName = "pField" & b
  349.                 pVal = dictrng1(key)(pName)
  350.                 arr(i, b + 2) = pVal
  351.             Next b
  352.             i = i + 1
  353.             arr(i, 1) = "Rng2"
  354.             arr(i, 2) = "'" & key
  355.             For b = 1 To numFields
  356.                 pName = "pField" & b
  357.                 pVal = dictrng2(key)(pName)
  358.                 pVal2 = dictrng1(key)(pName)
  359.                 arr(i, b + 2) = pVal
  360.                 If pVal <> pVal2 And Not dictIgnoreHdr.Exists(pName) Then
  361.                     arr2(i, b + 2) = 2
  362.                 End If
  363.             Next b
  364.             i = i + 1
  365.         End If
  366.     End If
  367. Next key
  368. If i2 = i Then arr(i, 1) = "No differences"
  369.  
  370. 'Clear memory
  371. Set dictrng1 = Nothing
  372. Set dictrng2 = Nothing
  373. Set rng1 = Nothing
  374. Set rng2 = Nothing
  375.  
  376. 'Write to sht
  377. Set newBk = Workbooks.Add
  378. Set ws = newBk.Sheets(1)
  379. ws.Cells(1, 1).Resize(UBound(arr, 1), UBound(arr, 2)) = arr
  380. For i = LBound(arr2, 1) To UBound(arr2, 1)
  381.     For b = LBound(arr2, 2) To UBound(arr2, 2)
  382.     If arr2(i, b) = 1 Then
  383.         ws.Cells(i, b).Font.Bold = True
  384.     ElseIf arr2(i, b) = 1.1 Then
  385.         ws.Cells(i, b).Font.Bold = True
  386.         ws.Cells(i, b).Font.Color = RGB(128, 128, 128)
  387.     ElseIf arr2(i, b) = 2 Then
  388.         ws.Cells(i, b).Interior.Color = RGB(255, 255, 0)
  389.     End If
  390.     Next b
  391. Next i
  392.  
  393. 'Touchups
  394. ws.Cells.Columns.AutoFit
  395. ws.Columns(1).ColumnWidth = 10
  396. ws.Columns(2).Delete
  397. FormatCurrencyColumns ws
  398.  
  399. skipdown:
  400. 'ENVIRONMENT SETTINGS
  401. Optimize False
  402.  
  403. End Sub
  404.  
  405. 'MODULE2 - SECONDARY ROUTINES
  406.  
  407. Function GetUniqueKey(dict As Dictionary, key As String) As String
  408.  
  409. Dim newKey As String
  410. Dim suffix As Long
  411.  
  412. newKey = key
  413. suffix = 1
  414.  
  415. While dict.Exists(newKey)
  416.     newKey = key & "-" & suffix
  417.     suffix = suffix + 1
  418. Wend
  419.  
  420. GetUniqueKey = newKey
  421.  
  422. End Function
  423.  
  424. 'Adjusts Excel settings for faster VBA processing
  425. Public Sub Optimize(ByVal Toggle As Boolean)
  426.     Application.ScreenUpdating = Not Toggle
  427.     Application.EnableEvents = Not Toggle
  428.     Application.DisplayAlerts = Not Toggle
  429.     Application.EnableAnimations = Not Toggle
  430.     Application.DisplayStatusBar = Not Toggle
  431.     Application.PrintCommunication = Not Toggle
  432.     Application.Calculation = IIf(Toggle, xlCalculationManual, xlCalculationAutomatic)
  433. End Sub
  434.  
  435. Sub DeOptimize()
  436. Optimize False
  437. End Sub
  438.  
  439. Function IsColumnBlank(arr As Variant, colIndex As Byte) As Boolean
  440.     Dim i As Long
  441.     Dim numRows As Long
  442.    
  443.     ' Get the number of rows in the array
  444.    numRows = UBound(arr, 1) ' Assuming the array is 2D and the first dimension is rows
  445.    
  446.     ' Loop through each row in the specified column
  447.    For i = 1 To numRows
  448.         ' Check if the cell is not empty, null, or a blank string
  449.        If Not IsEmpty(arr(i, colIndex)) And Not IsNull(arr(i, colIndex)) And arr(i, colIndex) <> "" Then
  450.             IsColumnBlank = False
  451.             Exit Function
  452.         End If
  453.     Next i
  454.    
  455.     ' If we loop through all rows without finding non-blank cells, return True
  456.    IsColumnBlank = True
  457. End Function
  458.  
  459. Function IsEqual(rec1 As Object, rec2 As Object, excludeDict As Object) As Boolean
  460.  
  461. Dim pVal1 As Variant, pVal2 As Variant
  462. Dim cond1 As Boolean, cond2 As Boolean
  463. Dim i As Byte
  464. Dim key As Variant
  465.  
  466. IsEqual = False
  467. For Each key In rec1.Keys
  468.     pVal1 = rec1(key)
  469.     pVal2 = rec2(key)
  470.     cond1 = pVal1 = pVal2
  471.     cond2 = excludeDict.Exists(key)
  472.     If Not cond1 And Not cond2 Then Exit Function
  473. Next key
  474. IsEqual = True
  475.  
  476. End Function
  477. Sub FormatCurrencyColumns(ws As Worksheet)
  478.  
  479.     Dim colRange As Range
  480.     Dim cell As Range
  481.     Dim decimalCount As Long
  482.     Dim totalNonEmptyCells As Long
  483.     Dim lastRow As Long
  484.     Dim lastCol As Long
  485.     Dim col As Long
  486.     Dim threshold As Double
  487.    
  488.     ' Get the last used row and column in the active sheet
  489.    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
  490.     lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
  491.    
  492.     ' Set threshold (e.g., 50%)
  493.    threshold = 0.5
  494.    
  495.     ' Loop through each column in the used range
  496.    For col = 1 To lastCol
  497.         ' Define the range for the entire used column
  498.        Set colRange = ws.Range(ws.Cells(1, col), ws.Cells(lastRow, col))
  499.        
  500.         ' Initialize counters
  501.        decimalCount = 0
  502.         totalNonEmptyCells = 0
  503.        
  504.         ' Iterate through the column
  505.        For Each cell In colRange
  506.             If IsNumeric(cell.value) Then
  507.                 totalNonEmptyCells = totalNonEmptyCells + 1
  508.                 If InStr(CStr(cell.value), ".") > 0 Then
  509.                     decimalCount = decimalCount + 1
  510.                 End If
  511.             End If
  512.         Next cell
  513.        
  514.         ' Determine if the majority of non-empty cells are numbers with decimals
  515.        If totalNonEmptyCells > 0 And (decimalCount / totalNonEmptyCells) >= threshold Then
  516.             ' Apply comma style to the entire column
  517.            colRange.NumberFormat = "#,##0.00"
  518.         End If
  519.     Next col
  520.    
  521.     'MsgBox "Currency formatting applied where applicable."
  522. End Sub
  523.  
  524.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement