I was trying to create a universal, error resistant VBA code that would count words in selected ranges as MS Word does. This below is the best I could do and I was hoping that somebody would have a look and let me know if I missed something or suggest any improvements. The code is quite fast and works with single cell, non-adjacent cells and whole columns, I need it to be as universal as possible. I'll be looking forward to feedback.
Option Explicit
Sub word_count()
Dim r() As Variant 'array
Dim c As Long 'total counter
Dim i As Long
Dim l As Long 'string lenght
Dim c_ch As Long 'character counter
Dim c_s As String 'string variable
Dim cell As range
Dim rng As range
If Selection Is Nothing Then
MsgBox "Sorry, you need to select a cell/range first", vbCritical
Exit Sub
ElseIf InStr(1, Selection.Address, ":", vbTextCompare) = 0 And InStr(1, Selection.Address, ",", vbTextCompare) = 0 Then 'for when only one cell is selected
word_count_f Selection.Value, c
MsgBox "Your selected cell '" & Replace(Selection.Address, "$", "") & "' in '" & Selection.Parent.Name & "' has " & c & " words."
Exit Sub
ElseIf InStr(1, Selection.Address, ",", vbTextCompare) > 0 Then 'when user selects more than one cell by clicking one by one -> address looks like ('A1,A2,A3') etc
Application.ScreenUpdating = False
Dim help() As Variant
ReDim help(1 To Selection.Cells.Count)
i = 1
For Each cell In Selection 'loading straigh to array wouldn't work, so I create a helper array
help(i) = cell.Value
i = i + 1
Next cell
r = help
Else 'load selection to array to improve speed
Application.ScreenUpdating = False
r = Selection.Value
End If
Dim item As Variant
For Each item In r
word_count_f item, c
Next item
MsgBox "Your selected range '" & Replace(Selection.Address, "$", "") & "' in '" & Selection.Parent.Name & "' has " & c & " words."
End Sub
Private Function word_count_f(ByVal item As Variant, ByRef c As Long)
Dim l As Long 'lenght variable
Dim c_s As String 'whole string variable
Dim c_ch As Long 'characted count variable
l = Len(item)
If l = 0 Then Exit Function
c_s = item
c_s = Trim(c_s)
Do While InStr(1, c_s, " ", vbTextCompare) > 0 'remove double spaces to improve accuracy
c_s = Replace(c_s, " ", " ")
Loop
If InStr(1, c_s, " ", vbTextCompare) = 0 And l > 0 Then 'if there was just one word in the cell
c = c + 1
ElseIf InStr(1, c_s, " ", vbTextCompare) > 0 Then 'else loop through string to count words
For c_ch = 1 To l 'loop through charactes of the string
If (Mid(c_s, c_ch, 1)) = " " Then
c = c + 1 'for each word
End If
Next c_ch
c = c + 1 'add one for the first word in cell
Else 'hopefully useless msgbox, but I wanted to be sure to inform the user correctly
MsgBox "Sorry, there was an error while processing one of the cells, the result might not be accurate", vbCritical
End If
End Function
You can achieve this in a similar way but with less code if you are interested to see?:
Sub word_count()
start_time = Timer
Dim r As Variant 'temp split array
Dim arr As Variant 'array
Dim c As Long 'total counter
If Selection Is Nothing Then
MsgBox "Sorry, you need to select a cell/range first", vbCritical
Exit Sub
Else
c = 0
For Each partial_selection In Split(Selection.Address, ",")
If Range(partial_selection).Cells.Count > 1 Then
arr = Range(partial_selection).Value
Else
Set arr = Range(partial_selection)
'single cell selected don't convert to array
End If
For Each temp_cell In arr
If Len(Trim(temp_cell)) > 0 Then
r = Split(temp_cell, " ")
For Each temp_word In r
If Len(Trim(temp_word)) > 0 Then
c = c + 1
'If the word is just a blank space don't count
End If
Next
'c = c + (UBound(r) - LBound(r) + 1)
'trimmed = Trim(temp_cell)
'c = c + 1 + (Len(trimmed) - Len(Replace(trimmed, " ", "")))
Else 'Blank cell
'Do nothing
End If
Next
Next
End If
Dim item As Variant
time_taken = Round(Timer - start_time, 3)
MsgBox "Your selected range '" & Replace(Selection.Address, "$", "") _
& "' in '" & Selection.Parent.Name & "' has " & c & " words." _
& vbNewLine & "Time Taken: " & time_taken & " secs"
Debug.Print c & " in "; time_taken; " secs"
End Sub
You could try this sort of approach? There may be the need to check for the next character to the space being another space, which would need some additions made. To detect word one as being the same as word one in the count. Also, transferring the range to an array would make it a touch faster.
Function Word_Count(rng As Excel.Range) As Long
Dim c As Excel.Range
Dim s As String
Dim l As Long
For Each c In rng.Cells
s = Trim(c.Value)
If s <> "" Then
If InStr(1, s, " ") > 0 Then
' Find number of spaces. You can use the ubound of split maybe here instead
l = l + (Len(s) - Len(Replace(s, " ", "")))
Else
End If
' Will always be 1 word
l = l + 1
End If
Next c
Word_Count = l
Set c = Nothing
End Function
Related
I've written the below code to search for a value(Supplier Name) in sheet "Fusion" Column H in sheet "CX" column D. I'm also doing a check the other way around so if the same value(Supplier Name) in sheet CX is in sheet "Fusion". I'm not looking for an Exact match hence the use of Instr and doing the comparison both ways as i'm not sure how a user has entered the information in either sheet.
The data type in either cell should be text.
If a match is found then in the last column of sheet "CX" it should just populate either "Supplier Found" or "Supplier Not Found"
Currently it's not populating the last column with any data but the Macro isn't erroring at any point.
I've tried adding msgboxes and "Here" and "Here3" are being triggered but it doesn't seem to be hitting the section of code that is "Here2" so I think it's there that's causing the issue but not sure how to resolve it.
Screenshot of my Data is :CX Sheet
Fusion Sheet
Any help would be greatly appreciated.
Option Explicit
Sub CompareCXFusion()
Dim CX As Worksheet
Dim Fusion As Worksheet
Dim strTemp as string
Dim strCheck as string
Dim i As Long, J As Long
Dim CXArr As Variant
Dim FusionArr As Variant
Dim match As Boolean
Dim CXRng As Range
Dim FusionRng As Range
Set CX = ActiveWorkbook.Sheets("CX")
Set Fusion = ActiveWorkbook.Sheets("Fusion")
Set CXRng = CX.Range("A2", CX.Cells(Rows.Count, "A").End(xlUp).Offset(0, 6))
Set FusionRng = Fusion.Range("A2", Fusion.Cells(Rows.Count, "A").End(xlUp).Offset(0, 9))
CXArr = CXRng.Value2
FusionArr = FusionRng.Value2
strTemp = lcase(trim(FusionArr(J, 7)))
strCheck = lcase(trim(CXArr(i, 3)))
For i = 1 To UBound(CXArr)
Match = False
For J = 1 To UBound(FusionArr)
MsgBox "Here"
If (Instr(strTemp, strCheck) > 0) OR (InStr(strCheck, strTemp) > 0) Then
MsgBox"Here2"
CXArr(i, 6) = "Supplier Found"
Else
Msgbox"Here3"
CXArr(i, 6) = "Supplier not found"
End If
Next J
Next i
End Sub
The expected output i'd expect is: If in Column H of Fusion the Supplier Name is "Supplier A" and the value in Column D of sheet "CX" is "Supplier A LTD" then i'd expect it to populate column G in sheet CX with "Supplier Found" due to it being found in the string.
If you need any more info please let me know.
I don't know how to correctly insert examples of my data else I would have
Option Explicit
Sub CompareCXFusion()
Dim CX As Worksheet
Dim Fusion As Worksheet
Dim i As Long, J As Long, lastRowCX As Long, lastRowFU As Long
Dim CXText As String, FusionText As String
Dim match As Boolean
Dim CXRng As Range, FusionRng As Range
Set CX = ActiveWorkbook.Sheets("CX")
Set Fusion = ActiveWorkbook.Sheets("Fusion")
lastRowCX = CX.Range("D1").SpecialCells(xlCellTypeLastCell).Row - 1
lastRowFU = Fusion.Range("H1").SpecialCells(xlCellTypeLastCell).Row - 1
Set CXRng = CX.Range("D1:D" & lastRowCX)
Set FusionRng = Fusion.Range("H1:H" & lastRowFU)
For i = 1 To lastRowCX
match = False
For J = 1 To lastRowFU
'Debug.Print "Here"
FusionText = FusionRng.Range("A1").Offset(J, 0).Value
CXText = CXRng.Range("A1").Offset(i, 0).Value
If FusionText <> "" And CXText <> "" Then
If InStr(FusionText, CXText) Or InStr(CXText, FusionText) Then
'Debug.Print "Here2"
match = True
End If
End If
Next J
'Result goes to column G of CX range:
If match Then
CXRng.Range("A1").Offset(i, 3).Value = "Supplier found" ' "Supplier found - " & i & " - " & CXRng.Range("A1").Offset(i, 0).Address & " - " & CXRng.Range("A1").Offset(i, 3).Address
Else
CXRng.Range("A1").Offset(i, 3).Value = "Supplier NOT found" '"Supplier NOT found - " & i & " - " & CXRng.Range("A1").Offset(i, 0).Address & " - " & CXRng.Range("A1").Offset(i, 3).Address
End If
Next i
End Sub
You need to make sure to check for case sensitivity:
Dim strTemp as string
Dim strCheck as string
'Inside for I loop
'Inside for j Loop
strTemp = lcase(trim(FusionArr(J, 7)))
strCheck = lcase(trim(CXArr(i, 3)))
If (Instr(strTemp, strCheck) > 0) OR (InStr(strCheck, strTemp) > 0) Then
'...
End If
'end for j
'end for i
I want to trim a string in MS Excel each cell to 100 characters in a column with 500 cells.
Starting with first cell, check if string length is or equal 100 characters. If the words are more than 100, then remove 1 word in the cell, then check again, if it's more than 100 remove another word until the string is less to 100. Then paste the less than 100 character string into the same cell replacing previous more than 100 character string.
Then move to another cell and replete the previous step.
The words to be removed are in an array
Here is my code so far
Sub RemoveWords()
Dim i As Long
Dim cellValue As String
Dim stringLenth As Long
Dim myString As String
Dim words() As Variant
words = Array("Many", "specific ", "Huawei", "tend", "Motorolla", "Apple")
myString = "Biggest problem with many phone reviews from non-tech specific publications is that its reviewers tend to judge the phones in a vacuum"
For i = 1 To 13
cellValue = Cells(i, 4).Value
If Not IsEmpty(cellValue) Then
stringLength = Len(cellValue)
' test if string is less than 100
If stringLength > 100 Then
Call replaceWords(cellValue, stringLength, words)
Else
' MsgBox "less than 100 "
End If
End If
Next i
End Sub
Public Sub replaceWords(cellValue, stringLength, words)
Dim wordToRemove As Variant
Dim i As Long
Dim endString As String
Dim cellPosition As Variant
i = 0
If stringLength > 100 Then
For Each wordToRemove In words
If InStr(1, UCase(cellValue), UCase(wordToRemove )) = 1 Then
MsgBox "worked word found" & " -- " & cellValue & " -- " & key
Else
Debug.Print "Nothing worked" & " -- " & cellValue & " -- " & key
End If
Next wordToRemove
Else
MsgBox "less than 100 "
End If
End Sub
Sub NonKeyWords()
' remove non key words
'
Dim i As Long
Dim cellValue As String
Dim stringLenth As Long
Dim wordToRemove As Variant
Dim words() As Variant
Dim item As Variant
' assign non-key words to array
words = words = Array("Many", "specific ", "Huawei", "tend", "Motorolla", "Apple")
' loop though all cells in column D
For i = 2 To 2000
cellValue = Cells(i, 4).Value
If Not IsEmpty(cellValue) Then
' test if string is less than 100
If Len(cellValue) > 100 Then
'Debug.Print "BEFORE REMOVING: " & cellValue
Call replaceWords(cellValue, words, i)
Else
' MsgBox "less than 100"
End If
End If
Next i
End Sub
Public Sub replaceWords(cellValue, words, i)
If Len(cellValue) > 100 Then
For Each wordsToDelete In words
If Len(cellValue) > 100 Then
cellValue = Replace(cellValue, wordsToDelete, "")
'Debug.Print cellValue
Debug.Print "String length after removal = " & Len(cellValue)
Debug.Print "remove another word................"
'cells(i, 4).ClearContents
Cells(i, 4).Value = cellValue
Else
'exit
End If
Next
Else
Debug.Print "SAVE: " & cellValue
End If
End Sub
I have some code I'm working on where I need to detect if a cell has a particular word in it, and if it does, it inserts a particular string in the adjacent cell. However, I'm having issues doing the detection part of it! Here's what I have so far.
Sub searchandpaste()
Dim stopvar As Variant
Dim i As Variant
Dim j As Variant
Dim k As Variant
Dim TestVal1 As Variant
Dim TestVal2 As Variant
i = 0
j = 0
Do While stopvar = 0
i = i + 1
MsgBox ("Row " & i)
MsgBox ("j equals " & j)
'If the first cell is empty, that means we've hit the end of the worksheet, and it stops the do-while loop
TestVal1 = Cells(i, 1)
If TestVal1 = 0 Then
stopvar = 1
Else
TestVal2 = Cells(i, 6)
If IsEmpty(TestVal2) = True Then
MsgBox ("Detected Empty Cell in Column 6")
j = 1
ElseIf TestVal2 = "XXXX" Then
'This means we have a place we need to insert a value
MsgBox ("Detected XXXX in Column 6")
'We know at this point that in Cells(6,i) we have a value we need to insert. Thus, we need to search Cells(7,i) for key text
If IsNumeric(Cells(7, j).Find("CYLINDER")) Or IsNumeric(Cells(7, j).Find("CYLINDERS")) Or IsNumeric(Cells(7, j).Find("CYL")) = True Then
MsgBox ("Detected the string CYLINDER")
j = j + 1
MsgBox ("j equals " & j)
Else
MsgBox ("Did not detect the string CYLINDER")
End If
End If
End If
Loop
End Sub
I'll cut out the important part, here.
'We know at this point that in Cells(6,i) we have a value we need to insert. Thus, we need to search Cells(7,i) for key text
If IsNumeric(Cells(7, j).Find("CYLINDER")) Or IsNumeric(Cells(7, j).Find("CYLINDERS")) Or IsNumeric(Cells(7, j).Find("CYL")) = True Then
MsgBox ("Detected the string CYLINDER")
j = j + 1
MsgBox ("j equals " & j)
Else
MsgBox ("Did not detect the string CYLINDER")
End If
My intention is that this would search the string in cell (i,7) for different variations of the word Cylinder, and if it finds one, it'll return TRUE or FALSE (false would be a NAN, which is caught by the IsNumeric and turned to a FALSE), and let me know it detected it. However, this doesn't seem to be working.
Can anybody pinpoint my error?
Is there a better way to search the string? Like, could I just search for "CYL" and have it say it detected any of those variations?
You should use the InStr function to do the comparison like this:
If InStr(1, Cells(7, j), "CYLINDER") > 0 Or _
InStr(1, Cells(7, j), "CYLINDERS") > 0 Or _
InStr(1, Cells(7, j), "CYL") > 0 Then
MsgBox ("Detected the string CYLINDER")
j = j + 1
MsgBox ("j equals " & j)
Else
MsgBox ("Did not detect the string CYLINDER")
End If
For more information on this function visit MSDN at https://msdn.microsoft.com/en-us/library/office/gg264811%28v=office.15%29.aspx
To avoid different cases (as suggested by #Sgdva) you have several options:
If InStr(1, Cells(7, j), "CYLINDER", vbTextCompare) > 0 Or _
InStr(1, Cells(7, j), "CYLINDERS", vbTextCompare) > 0 Or _
InStr(1, Cells(7, j), "CYL", vbTextCompare) > 0 Then
MsgBox ("Detected the string CYLINDER")
j = j + 1
MsgBox ("j equals " & j)
Else
MsgBox ("Did not detect the string CYLINDER")
End If
OR
If InStr(1, UCase(Cells(7, j)), "CYLINDER") > 0 Or _
InStr(1, UCase(Cells(7, j)), "CYLINDERS") > 0 Or _
InStr(1, UCase(Cells(7, j)), "CYL") > 0 Then
MsgBox ("Detected the string CYLINDER")
j = j + 1
MsgBox ("j equals " & j)
Else
MsgBox ("Did not detect the string CYLINDER")
End If
OR
Use the Option Compare Text at the top of your module and as pointed out here:
https://msdn.microsoft.com/en-us/library/office/gg278697.aspx
At the same time, you might want to consider inserting the line:
Option Explicit
(for good coding practice).
Not sure what you are trying to accomplish with the j variable as it doesn't seem to have any relevance. Except I seem to have identified an error in your code and the answer provided by Ralph. Cells(7, j) should rather be Cells(i, 7). Full code would be:
Sub searchandpaste()
Dim stopvar As Variant
Dim i As Variant
Dim j As Variant
Dim k As Variant
Dim TestVal1 As Variant
Dim TestVal2 As Variant
i = 0
j = 0
Do While stopvar = 0
i = i + 1
MsgBox ("Row " & i)
MsgBox ("j equals " & j)
'If the first cell is empty, that means we've hit the end of the worksheet, and it stops the do-while loop
TestVal1 = Cells(i, 1)
If TestVal1 = 0 Then
stopvar = 1
Else
TestVal2 = Cells(i, 6)
If IsEmpty(TestVal2) = True Then
MsgBox ("Detected Empty Cell in Column 6")
j = 1
ElseIf TestVal2 = "XXXX" Then
'This means we have a place we need to insert a value
MsgBox ("Detected XXXX in Column 6")
'We know at this point that in Cells(6,i) we have a value we need to insert. Thus, we need to search Cells(7,i) for key text
If InStr(LCase(Cells(i, 7)), "cyl") > 0 Then
MsgBox ("Detected the string CYLINDER")
j = j + 1
MsgBox ("j equals " & j)
Else
MsgBox ("Did not detect the string CYLINDER")
End If
End If
End If
Loop
End Sub
This is not a question, so much as a solution, but I wanted to share it here as I had gotten help for things I needed here.
I wanted to find a specific Excel sheet, in the Active Workbook, searching by the name of the sheet. I built this to find it. It is a "contains" search, and will automatically go to the sheet if it is found, or ask the user if there are multiple matches:
To end at any time, just enter a blank in the input box.
Public Sub Find_Tab_Search()
Dim sSearch As String
sSearch = ""
sSearch = InputBox("Enter Search", "Find Tab")
If Trim(sSearch) = "" Then Exit Sub
'MsgBox (sSearch)
Dim sSheets() As String
Dim sMatchMessage As String
Dim iWorksheets As Integer
Dim iCounter As Integer
Dim iMatches As Integer
Dim iMatch As Integer
Dim sGet As String
Dim sPrompt As String
iMatch = -1
iMatches = 0
sMatchMessage = ""
iWorksheets = Application.ActiveWorkbook.Sheets.Count
ReDim sSheets(iWorksheets)
'Put list of names in array
For iCounter = 1 To iWorksheets
sSheets(iCounter) = Application.ActiveWorkbook.Sheets(iCounter).Name
If InStr(1, sSheets(iCounter), sSearch, vbTextCompare) > 0 Then
iMatches = iMatches + 1
If iMatch = -1 Then iMatch = iCounter
sMatchMessage = sMatchMessage + CStr(iCounter) + ": " + sSheets(iCounter) + vbCrLf
End If
Next iCounter
Select Case iMatches
Case 0
'No Matches
MsgBox "No Match Found for " + sSearch
Case 1
'1 match activate the sheet
Application.ActiveWorkbook.Sheets(iMatch).Activate
Case Else
'More than 1 match. Ask them which sheet to go to
sGet = -1
sPrompt = "More than one match found. Please enter number from following list"
sPrompt = sPrompt + "to display the sheet" + vbCrLf + vbCrLf + sMatchMessage
sPrompt = sPrompt + vbCrLf + vbCrLf + "Enter blank to cancel"
sGet = InputBox(sPrompt, "Please select one")
If Trim(sGet) = "" Then Exit Sub
sPrompt = "Value must be a number" + vbCrLf + vbCrLf + sPrompt
Do While IsNumeric(sGet) = False
sGet = InputBox(sPrompt, "Please select one")
If Trim(sGet) = "" Then Exit Sub
Loop
iMatch = CInt(sGet)
Application.ActiveWorkbook.Sheets(iMatch).Activate
End Select
End Sub
I hope someone finds this useful, and would also welcome enhancement suggestions.
For fun tried to do this in as few lines as possible with loops
Uses a range name, xlm, and VBS under utilised Filter to provide the same multi-sheet search functionality as above.
The bulk of the code relates to the sheet selection portion
Sub GetNAmes()
Dim strIn As String
Dim X
strIn = Application.InputBox("Search string", "Enter string to find", ActiveSheet.Name, , , , , 2)
If strIn = "False" Then Exit Sub
ActiveWorkbook.Names.Add "shtNames", "=RIGHT(GET.WORKBOOK(1),LEN(GET.WORKBOOK(1))-FIND(""]"",GET.WORKBOOK(1)))"
X = Filter([index(shtNames,)], strIn, True, 1)
Select Case UBound(X)
Case Is > 0
strIn = Application.InputBox(Join(X, Chr(10)), "Multiple matches found - type position to select", , , , , 1)
If strIn = "False" Then Exit Sub
On Error Resume Next
Sheets(CStr(X(strIn))).Activate
On Error GoTo 0
Case 0
Sheets(X(0)).Activate
Case Else
MsgBox "No match"
End Select
End Sub
Counting distinct values in excel - frequency function
yes I have read
Counting distinct values in excel - frequency function
I am try to count a column with different numbers
column contains (search)
1 3 7 9 5 1 3 9 4
result looking for;
C1 C2
1 = 2
2 = 0
3 = 2
4 = 1
etc
You can use COUNTIF to count the number of elements that match a condition.
Suppose you have your numbers in column A, say from A1 to A10:
A1: 1
A2: 3
A3: 7
etc...
Type in somewhere on your sheet, say in column B, the values you are interested in:
B1: 0
B2: 1
etc...
and in C1, type in
=COUNTIF($A$1:$A$10, B1)
This should count the number of values equal to B1 (i.e. 0), in A1:A10.
Enter your numbers in column A and a sequence in column B
A B
1 1
2 1
3 1
4 1
2 1
3 1
4 1
Select both columns and create a pivot table putting col A in rows. Select {COUNT} as function and you are done.
Not exactly what you are asking but i use a macro to generate frequency tables. I like it. Original code was posted by MWE at http://www.vbaexpress.com/kb/getarticle.php?kb_id=406 and i have (hopefully) improved it a bit. Have left in a little bit of redundant code so i get more replies :p
Sub zzzFrequencyDONT_SELECT_WHOLE_COLUMN()
' if user selects massive range - usually whole column - stops them
If Selection.Rows.Count > 60000 Then
MsgBox "Range selected is way too large - over 60,000. You have probably selected an entire column. Select a range of under 60,000 cells and try again"
End If
If Selection.Rows.Count > 60000 Then
Exit Sub
End If
'
' Function computes frequency count of unique values in a selection
'
Dim Count() As Integer
Dim I As Integer, J As Integer
Dim Num As Integer, NumOK As Integer, MaxNumOK As Integer, NumBad As Integer
Dim Row As Integer, Col As Integer, Temp1 As Integer, Temp2 As Integer
Dim strBuffer As String, strBadVals As String
Dim CellVal As Variant
Dim Ans As VbMsgBoxResult
Num = 0
NumBad = 0
NumOK = 0
MaxNumOK = 50
ReDim Count(MaxNumOK, 2)
strBuffer = ""
'
' sequence through each cell in selection
'
For Each Cell In Selection
Num = Num + 1
On Error Resume Next
CellVal = Cell.Value
Select Case Err
Case Is = 0
'
' no error, examine type
'
Select Case LCase(TypeName(CellVal))
Case "integer", "long", "single", "double"
'
' numeric type; if single or double, use
' Fix function to reduce to integer portion
'
If TypeName(CellVal) = "single" Or _
TypeName(CellVal) = "double" Then
CellVal = Fix(CellVal)
End If
'
' check if previously seen
' if so, simply bump counter
' if not, increment NumOK and store value
'
For I = 1 To NumOK
If CellVal = Count(I, 1) Then
Count(I, 2) = Count(I, 2) + 1
GoTo NextCell
End If
Next I
NumOK = NumOK + 1
If NumOK > MaxNumOK Then
MsgBox "capacity of freq count proc exceeded" & vbCrLf & _
"Displaying results so far", vbCritical
GoTo SortCount
End If
Count(NumOK, 1) = CellVal
Count(NumOK, 2) = 1
Case Else
NumBad = NumBad + 1
If Cell.Text <> "" Then
strBadVals = strBadVals & Cell.Text & vbCrLf
Else
strBadVals = strBadVals & "<blank>" & vbCrLf
End If
End Select
Case Is <> 0
NumBad = NumBad + 1
If Cell.Text <> "" Then
strBadVals = strBadVals & Cell.Text & vbCrLf
Else
strBadVals = strBadVals & "<blank>" & vbCrLf
End If
End Select
NextCell:
Next Cell
'
' counting done, sort data
'
SortCount:
For I = 1 To NumOK
For J = I To NumOK
If I <> J Then
If Count(I, 1) > Count(J, 1) Then
Call SwapVals(Count(I, 1), Count(J, 1))
Call SwapVals(Count(I, 2), Count(J, 2))
End If
End If
Next J
Next I
'
' store count data for display
'
Dim percentstore As Single
percentstore = Str(Count(I, 2)) / Str(Num)
For I = 1 To NumOK
strBuffer = strBuffer & Str(Count(I, 1)) & vbTab + Str(Count(I, 2)) & vbTab & FormatPercent(Str(Count(I, 2)) / Str(Num)) & vbCr
Next I
'
' display results
'
MsgBox "CTRL C to copy" & vbCrLf & _
"# cells examined = " & Str(Num) & vbCrLf & _
"# cells w/o acceptable numerical value = " & NumBad & vbCrLf & _
"# unique values found = " & NumOK & vbCrLf & _
"Frequency Count:" & vbCrLf & "value" & vbTab & "frequency" & vbTab & "Percent" & vbCr + strBuffer, vbInformation, "Frequency count - CTRL C to copy"
If NumBad > 0 Then
Ans = MsgBox("display non-numerics encountered?", vbQuestion & vbYesNo)
If Ans = vbYes Then MsgBox "Non Numerics encountered" & vbCrLf & strBadVals
End If
'
' write to worksheet?
'
' Ans = MsgBox("Ok to write out results below selection?" & vbCrLf + _
' "results will be two cols by " & (NumOK + 1) & " rows", vbQuestion + vbYesNo)
' If Ans <> vbYes Then Exit Sub
' Row = Selection.Row + Selection.Rows.Count
' Col = Selection.Column
' Cells(Row, Col) = "Value"
' Cells(Row, Col + 1) = "Count"
' For I = 1 To NumOK
' Cells(Row + I, Col) = Count(I, 1)
' Cells(Row + I, Col + 1) = Count(I, 2)
' Next I
End Sub
Sub SwapVals(X, Y)
'
' Function swaps two values
'
Dim Temp
Temp = X
X = Y
Y = Temp
End Sub