Skip to main content
Code Review

Return to Answer

Commonmark migration
Source Link

###Manually assigning column letters

Manually assigning column letters

###Variables

Variables

###Error Handling

Error Handling

###Select

Select

###Last Row

Last Row

###Readability

Readability

###Manually assigning column letters

###Variables

###Error Handling

###Select

###Last Row

###Readability

Manually assigning column letters

Variables

Error Handling

Select

Last Row

Readability

Post Undeleted by Raystafarian
added 4444 characters in body
Source Link
Raystafarian
  • 7.3k
  • 1
  • 23
  • 60

Manually###Manually assigning column letters

This saves you from running the Asc and it also makes it more clear when assigning the ranges. Now you set it up top and if you need to change it, just change it there.

So it would be

Const TOTAL_TIME As Long = 8
Const CALL_NUMBER As Long = 3
Const TYPE_COLUMN As Long = 13
Const NUMBER_CALLED As Long = 9
Const UNIQUE_COLUMN As Long = 14
Const DURATION_COLUMN As Long = 15
Const LAST_DIGIT_COLUMN As Long = 16

###Variables

Always turn on Option Explicit. You can have it automatically by going to Tools -> Options in the VBE and checking the Require Variable Declaration option. This way if you have any variables not defined, the compiler will let you know.

Variables infi, filename and cafi are not declared.

When you don't define your variable, VBA will declare it as a Variant type that can hold any type of data. While this may be more flexible, it adds processing time to your macro as VBA decides or tests for the type. Additionally, since a Variant can be any type of data, you may miss out on valuable troubleshooting information on Type Mismatch

Additionally, your naming could be improved. See how you needed comments next to all your variable declarations?

Dim TT As String '/ Column Letter for Total Time in seconds
Dim TTN As Long '/ Column # for Total time in seconds
Dim TTR As Range '/ Column as Range Total time
Dim CN As String '/ Column Letter for Call Number
Dim CNN As Long '/ Column # for Call Number
Dim CNR As Range '/ Column as Range Call Number

Comments - "code tell you how, comments tell you why" . The code should speak for itself, if it needs a comment, it might need to be made more clear. If not, the comment should describe why you're doing something rather than how you're doing it. Here are a few reasons to avoid comments all together.

Use the variable's name to tell us what it does. TTN means nothing to the reader - he/she needs to go back up to look at the comment. Whereas if it was just called totalTimeColumnNumber (for instance) it would be clear.

###Error Handling

This line right here

Set cafi = ActiveWorkbook.Sheets("Calls")

needs some error handling. What if it doesn't exist? Furthermore, Worksheets have a CodeName property - View Properties window (F4) and the (Name) field (the one at the top) can be used as the worksheet name. This way you can avoid Sheets("calls") and instead just use Calls.

###Select

cafi.Activate
Cells(1, 1).Select

Be sure to avoid things like .Select - it just slows the code down by needing to fiddle with the spreadsheet while doing everything else behind the scenes. There's a good question on StackOverflow addressing this . Essentially, since you're doing everything in the development environment, there's no need to leave it. Just get the data, do your stuff and spit it back out.

###Last Row

Set TTR = .Range(.Cells(1, TTN), .Cells(1, TTN).End(xlDown))

You pretty much never want to use xlDown when defining a range. There is a standard way to find lastRow and lastColumn. That post explains why.

###Readability

Take this if for instance

If Cells(TyLo, TTN).Value > 1 And Cells(TyLo, TTN).Value < 30 Then
 Cells(TyLo, TYN + 2).Value = ">1"
ElseIf Cells(TyLo, TTN).Value > 30 And Cells(TyLo, TTN).Value < 60 Then
 Cells(TyLo, TYN + 2).Value = ">30"
ElseIf Cells(TyLo, TTN).Value > 60 And Cells(TyLo, TTN).Value < 600 Then
 Cells(TyLo, TYN + 2).Value = ">60"
ElseIf Cells(TyLo, TTN).Value > 600 Then
 Cells(TyLo, TYN + 2).Value = ">600"
Else: Cells(TyLo, TYN + 2).Value = "Missed Call"
End If

Can you look at that and tell what's happening - because I can't. Even just a simple change in structure would make it more readable

Dim printOut As String
Dim length As Long
length = Sheet1.Cells(TyLo, tnn).Value
Select Case length
 Case 0
 printOut = "Missed Call"
 Case 1 To 19
 printOut = ">1"
 Case 30 To 59
 printOut = ">30"
 Case 60 To 599
 printOut = ">60"
 Case Else
 printOut = ">600"
End Select
Sheet1.Cells(TyLo, tnn + 2).Value = printOut

I know that doesn't do exactly what yours does, but without the data I can't make many inferences.

Manually assigning column letters

This saves you from running the Asc and it also makes it more clear when assigning the ranges. Now you set it up top and if you need to change it, just change it there.

###Manually assigning column letters

This saves you from running the Asc and it also makes it more clear when assigning the ranges. Now you set it up top and if you need to change it, just change it there.

So it would be

Const TOTAL_TIME As Long = 8
Const CALL_NUMBER As Long = 3
Const TYPE_COLUMN As Long = 13
Const NUMBER_CALLED As Long = 9
Const UNIQUE_COLUMN As Long = 14
Const DURATION_COLUMN As Long = 15
Const LAST_DIGIT_COLUMN As Long = 16

###Variables

Always turn on Option Explicit. You can have it automatically by going to Tools -> Options in the VBE and checking the Require Variable Declaration option. This way if you have any variables not defined, the compiler will let you know.

Variables infi, filename and cafi are not declared.

When you don't define your variable, VBA will declare it as a Variant type that can hold any type of data. While this may be more flexible, it adds processing time to your macro as VBA decides or tests for the type. Additionally, since a Variant can be any type of data, you may miss out on valuable troubleshooting information on Type Mismatch

Additionally, your naming could be improved. See how you needed comments next to all your variable declarations?

Dim TT As String '/ Column Letter for Total Time in seconds
Dim TTN As Long '/ Column # for Total time in seconds
Dim TTR As Range '/ Column as Range Total time
Dim CN As String '/ Column Letter for Call Number
Dim CNN As Long '/ Column # for Call Number
Dim CNR As Range '/ Column as Range Call Number

Comments - "code tell you how, comments tell you why" . The code should speak for itself, if it needs a comment, it might need to be made more clear. If not, the comment should describe why you're doing something rather than how you're doing it. Here are a few reasons to avoid comments all together.

Use the variable's name to tell us what it does. TTN means nothing to the reader - he/she needs to go back up to look at the comment. Whereas if it was just called totalTimeColumnNumber (for instance) it would be clear.

###Error Handling

This line right here

Set cafi = ActiveWorkbook.Sheets("Calls")

needs some error handling. What if it doesn't exist? Furthermore, Worksheets have a CodeName property - View Properties window (F4) and the (Name) field (the one at the top) can be used as the worksheet name. This way you can avoid Sheets("calls") and instead just use Calls.

###Select

cafi.Activate
Cells(1, 1).Select

Be sure to avoid things like .Select - it just slows the code down by needing to fiddle with the spreadsheet while doing everything else behind the scenes. There's a good question on StackOverflow addressing this . Essentially, since you're doing everything in the development environment, there's no need to leave it. Just get the data, do your stuff and spit it back out.

###Last Row

Set TTR = .Range(.Cells(1, TTN), .Cells(1, TTN).End(xlDown))

You pretty much never want to use xlDown when defining a range. There is a standard way to find lastRow and lastColumn. That post explains why.

###Readability

Take this if for instance

If Cells(TyLo, TTN).Value > 1 And Cells(TyLo, TTN).Value < 30 Then
 Cells(TyLo, TYN + 2).Value = ">1"
ElseIf Cells(TyLo, TTN).Value > 30 And Cells(TyLo, TTN).Value < 60 Then
 Cells(TyLo, TYN + 2).Value = ">30"
ElseIf Cells(TyLo, TTN).Value > 60 And Cells(TyLo, TTN).Value < 600 Then
 Cells(TyLo, TYN + 2).Value = ">60"
ElseIf Cells(TyLo, TTN).Value > 600 Then
 Cells(TyLo, TYN + 2).Value = ">600"
Else: Cells(TyLo, TYN + 2).Value = "Missed Call"
End If

Can you look at that and tell what's happening - because I can't. Even just a simple change in structure would make it more readable

Dim printOut As String
Dim length As Long
length = Sheet1.Cells(TyLo, tnn).Value
Select Case length
 Case 0
 printOut = "Missed Call"
 Case 1 To 19
 printOut = ">1"
 Case 30 To 59
 printOut = ">30"
 Case 60 To 599
 printOut = ">60"
 Case Else
 printOut = ">600"
End Select
Sheet1.Cells(TyLo, tnn + 2).Value = printOut

I know that doesn't do exactly what yours does, but without the data I can't make many inferences.

Post Deleted by Raystafarian
Source Link
Raystafarian
  • 7.3k
  • 1
  • 23
  • 60

Manually assigning column letters

I have 4 variables for the specific columns I will be referencing (will probably need to add more before the end of this code). I manually assigned a letter because the columns will rarely if ever change. I then put a formula in to assign a variable to the column #

If you need the column number, just make the column numbers e.g. -

Const TOTAL_TIME As Long = 8
Const CALL_NUMBER As Long = 3

This saves you from running the Asc and it also makes it more clear when assigning the ranges. Now you set it up top and if you need to change it, just change it there.

lang-vb

AltStyle によって変換されたページ (->オリジナル) /