Several questions about a macro

JenniferMurphy

Well-known Member
Joined
Jul 23, 2011
Messages
2,531
Office Version
  1. 365
Platform
  1. Windows
The macro below works, but I have several questions about why I need to take certain steps and/or if there is a better way.

This macro adds 1 to one of 5 ace tallies (0-4). It works, but,
  • Why do I need to trim the spaces, if any. In the Immediate window ?"3 + " 4 " gets 7.
  • Why do I need to add 0 before comparing with the rounded version?
  • Am I making this harder than it needs to be?
VBA Code:
'====================================================================
'   Tally Aces macro -- Assigned to CS+Z
'
' Tallies are in named ranges Aces0, Aces1, Aces2, Aces3, & Aces4
'====================================================================
Sub TallyAces()

Const rnAces As String = "Aces" 'Base name for all ace tally cells

Dim NumAces As Variant  'The number of aces to tally
Const Prompt = "Enter number of aces (0-4)" & vbCrLf & vbCrLf _
               & "Click Cancel to quit"
Do
  'Get the reply and trim leading and trailng spaces
  NumAces = Trim(InputBox(Prompt, "TallyAces Macro", ""))
  'Cancel returns "", but so does ""
  If NumAces = "" Then Exit Do
  If Not IsNumeric(NumAces) Then GoTo Error
  'I had to add 0 to make this work
  If (NumAces + 0) <> Round(NumAces) Then GoTo Error
  If NumAces < 0 Or NumAces > 4 Then GoTo Error
 
  'Finally, do the tally
  Range(rnAces & NumAces).Select
  ActiveCell.Value = ActiveCell.Value + 1
  GoTo Continue
 
Error:
  MsgBox "Invalid data"
Continue:
Loop

End Sub

Thanks
 

Excel Facts

Copy formula down without changing references
If you have =SUM(F2:F49) in F50; type Alt+' in F51 to copy =SUM(F2:F49) to F51, leaving the formula in edit mode. Change SUM to COUNT.
Hello,

My suggestion is to let CInt () do the work:
VBA Code:
'====================================================================
'   Tally Aces macro
'
' Tallies are in named ranges Aces0, Aces1, Aces2, Aces3, & Aces4
'====================================================================
Sub TallyAcesNew()
Const rnAces As String = "Aces" 'Base name for all ace tally cells
Const Prompt = "Enter number of aces (0-4)" & vbCrLf & vbCrLf _
               & "Click Cancel to quit"
Dim NumAces As Variant  'The number of aces to tally
On Error GoTo ErrHdl
Do
    'Get the reply and trim leading and trailng spaces
    NumAces = InputBox(Prompt, "TallyAces Macro", "0")
    If NumAces = "" Then Exit Do
    NumAces = CInt(NumAces)
    If NumAces < 0 Or NumAces > 4 Then
Resume_CInt_Error:
        MsgBox "Invalid data"
    Else
        Range(rnAces & NumAces).Formula = Range(rnAces & NumAces) + 1
    End If
Loop
Exit Sub
ErrHdl:
Resume Resume_CInt_Error
End Sub

CInt will convert your variant into an integer which you then can compare to 0 and to 4, or the conversion will fail, resulting in an error which will take the sub to the ErrHdl and then resume at label Resume_CInt_Error. Of course it's not considered good programming style to jump right into the middle of an if statement but I decided to go for a quick & dirty approach.

In your original Sub you needed to get rid of spaces in NumAces not because of any integer treatment but because the Range "Aces1" is different from "Aces1 ", for example. You needed to add 0 before comparing to a Round() result in order to force VBA to make a number out of NumAces. Val(NumAces) would have worked as well.

Note that I have used the default value 0 in the input box because I thought that would be the most likely value you have to enter.

Regards,
Bernd
 
Upvote 0
Solution
Hello,

My suggestion is to let CInt () do the work:
The reason I didn't use CInt is because I didn't think of it. 😣 But even if I had, I would have needed to to do something to flag input that is a valid number, but not an integer.

In your original Sub you needed to get rid of spaces in NumAces not because of any integer treatment but because the Range "Aces1" is different from "Aces1 ", for example. You needed to add 0 before comparing to a Round() result in order to force VBA to make a number out of NumAces. Val(NumAces) would have worked as well.
Your array solution in the other thread led me to replace the 5 individual ranges with a single 1x5 range.

Note that I have used the default value 0 in the input box because I thought that would be the most likely value you have to enter.
That won't work for me. My poor typing skills cause me to inadvertantly hit the Enter key way too often.

Here's my updated macro:

VBA Code:
'====================================================================
'   Tally Aces macro -- Assigned to CS+Z
'
' Tallies are in the 1x5 named range: AceTallies
'
' 10/23/22 Helped by MrExcel thread 1220049.
'====================================================================
Sub TallyAces()
Const MyName As String = "TallyAces Macro"

Const rnAceTallies As String = "AceTallies" 'Range of tallies (0-4)

Dim vReply As Variant    'The number of aces to tally as entered
Dim nNumAces As Double   '.Converted to number
Dim iAceIndex As Integer '.Converted to integer
Const Prompt = "Enter number of aces (0-4)" & vbCrLf & vbCrLf _
               & "Click Cancel or press Enter to quit"
Do
  'Get the reply. X,Y coordinates by trial and error
  vReply = InputBox(Prompt, MyName, "", 11000, 5000)
  'Cancel returns "", but so does "", so confirm both
  If vReply = "" Then
    If vbYes = MsgBox("Click Yes to exit", vbYesNo, MyName) Then
      Exit Do
    Else
      GoTo Continue
    End If
  End If
  On Error GoTo BadInput
  nNumAces = CSng(vReply)       'Convert to number
  iAceIndex = CInt(nNumAces)    '.then to integer
  If nNumAces <> iAceIndex Then GoTo BadInput
  If iAceIndex < 0 Or iAceIndex > 4 Then GoTo BadInput
 
  'Finally, do the tally
  Range(rnAceTallies)(1, iAceIndex + 1).Select  'Select the cell within the array
  ActiveCell.Value = ActiveCell.Value + 1       '.add 1
  GoTo Continue
 
BadInput:
  MsgBox "Invalid data", vbOKOnly, MyName
Continue:
Loop

End Sub

And it works! Of course, if you have any other suggestions, please fire away.
 
Upvote 0
Hello,

If you are OK with the program, it's fine, of course.
I thought the variable nNumAces is not really needed, but if you like it, name it sngNumAces and declare it as Single because you assign it with CSng, I suggest.
On Error Goto is supposed to be used with an error handler which could simply resume to BadInput in this case.
Now, my suggestion was not the cleanest, either. So, if it ain't broke, don't fix it.

Regards,
Bernd
 
Upvote 0
It seems to be working. Here are the results of the first 500 deals:
Ace Odds.xlsm
BCDEFGHI
4#Aces0 Aces1 Ace2 Aces3 Aces4 Aces1-4 AcesTotals
5Tallies2821744220218500
6Expected2751833830225500
7Delta+7-9+4-1-0-7
8Prob55.0356%36.6904%7.6794%0.5818%0.0129%44.9644%100.0000%
9Actual56.4000%34.8000%8.4000%0.4000%0.0000%43.6000%100.0000%
10% Error+2.4792%-5.1522%+9.3838%-31.2444%-100.0000%-1.270128
11Combin7,7 = 17,1 = 77,2 = 217,3 = 357,4 = 35
12
13#Aces0 Aces1 Ace2 Aces3 Aces4 Aces1-4 AcesTotals
14Tallies2321343220168400
15Expected2201473120180400
16Delta+12-13+1-0-0-12
17Prob55.0356%36.6904%7.6794%0.5818%0.0129%44.9644%100.0000%
18Actual58.0000%33.5000%8.0000%0.5000%0.0000%42.0000%100.0000%
19% Error+5.3864%-8.6954%+4.1751%-14.0556%-100.0000%-1.185759
20Combin7,7 = 17,1 = 77,2 = 217,3 = 357,4 = 35
21
22#Aces0 Aces1 Ace2 Aces3 Aces4 Aces1-4 AcesTotals
23Tallies178962420122300
24Expected1651102320135300
25Delta+13-14+1+0-0-13
26Prob55.0356%36.6904%7.6794%0.5818%0.0129%44.9644%100.0000%
27Actual59.3333%32.0000%8.0000%0.6667%0.0000%40.6667%100.0000%
28% Error+7.8091%-12.7837%+4.1751%+14.5926%-100.0000%-0.940160
29Combin7,7 = 17,1 = 77,2 = 217,3 = 357,4 = 35
30
31#Aces0 Aces1 Ace2 Aces3 Aces4 Aces1-4 AcesTotals
32Tallies11864171082200
33Expected11073151090200
34Delta+8-9+2-0-0-8
35Prob55.0356%36.6904%7.6794%0.5818%0.0129%44.9644%100.0000%
36Actual59.0000%32.0000%8.5000%0.5000%0.0000%41.0000%100.0000%
37% Error+7.2034%-12.7837%+10.6860%-14.0556%-100.0000%-1.161532
38Combin7,7 = 17,1 = 77,2 = 217,3 = 357,4 = 35
39
40#Aces0 Aces1 Ace2 Aces3 Aces4 Aces1-4 AcesTotals
41Tallies632980037100
42Expected553781045100
43Delta+8-8+0-1-0-8
44Prob55.0356%36.6904%7.6794%0.5818%0.0129%44.9644%100.0000%
45Actual63.0000%29.0000%8.0000%0.0000%0.0000%37.0000%100.0000%
46% Error+14.4715%-20.9602%+4.1751%-100.0000%-100.0000%-2.167851
47Combin7,7 = 17,1 = 77,2 = 217,3 = 357,4 = 35
Aces
Cell Formulas
RangeFormula
H8:H10,H5:H6H5=SUM(D5:G5)
I8:I9,I5:I6I5=SUM(C5:G5)
C6:G6D6=TallyOdds*TotalDeals
C7:H7D7=D5-D6
C8:G8C8=COMBIN(4,SEQUENCE(1,5,0,1))*COMBIN(48,7-SEQUENCE(1,5,0,1))/COMBIN(52,7)
C9C9=C5/I5
D9D9=D5/I5
E9E9=E5/I5
F9F9=F5/I5
G9G9=G5/I5
C10:G10C10=C9/C8 - 1
C11C11="7,7 = " & COMBIN(7,7)
D11D11="7,1 = " & COMBIN(7,1)
E11E11="7,2 = " & COMBIN(7,2)
F11F11="7,3 = " & COMBIN(7,3)
G11G11="7,4 = " & COMBIN(7,4)
Dynamic array formulas.
Named Ranges
NameRefers ToCells
AceTallies=Aces!$C$5:$G$5I5, C9, C7
TallyOdds=Aces!$C$8:$G$8I8, C10, C6
TotalDeals=Aces!$I$5C9:G9, C6:G6
 
Upvote 0

Forum statistics

Threads
1,214,833
Messages
6,121,868
Members
449,053
Latest member
Mesh

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