Reputation: 247
I'm creating some code to better keep track of expenses. One of the macros is meant to load fixed expenses from another worksheet, only when the amounts are not empty and, in the case of credits, only if there's still pending payments.
My code is as follows:
Sub CargarFijos()
ActiveSheet.Range("J4").Select
If Not ActiveSheet.Previous Is Nothing Then
If Not ActiveSheet.Previous.Range("C12") Is Nothing Then
If Not IsEmpty(ActiveSheet.Previous.Range("C12")) Then
ActiveCell.Text = "Tarjeta de Credito"
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = ActiveSheet.Previous.Range("C12").Value
ActiveCell.Offset(1, -1).Select
End If
End If
End If
If Not IsEmpty(ActiveCell) Then
ActiveCell.Offset(1, 0).Select
End If
If Not Worksheets("Fijos") Is Nothing Then
For Each c In Worksheets("Fijos").Range("A2:A40").Cells
If Not c Is Nothing Then
If Not IsEmpty(c.Offset(0, 1)) And Not c.Offset(0, 1) Is Nothing Then
If IsEmpty(c.Offset(0, 2)) And Not c.Offset(0, 2) Is Nothing Then
ActiveCell.Text = c.Text
ActiveCell.Offset(0, 1).Value = c.Offset(0, 1).Value
ActiveCell.Offset(1, 0).Select
ElseIf Not c.Offset(0, 2) Is Nothing And c.Offset(0, 2).Value > 0 Then
ActiveCell.Text = c.Text
ActiveCell.Offset(0, 1).Value = c.Offset(0, 1).Value
c.Offset(0, 2).Value = c.Offset(0, 2).Value - 1
ActiveCell.Offset(1, 0).Select
End If
End If
End If
Next
End If
End Sub
My worksheet "Fijos" is where I have my fixed expenses. On column A I have the descriptions, on column B I have the amount to be payed, and on column C I have the pending payments.
The idea is that I run along the A column, check the B and C column and, if there's an amount to pay on column B and pending payments (or empty) on C, I add the amount of B on my ActiveSheet.
On my ActiveSheet, column J is the description of the expenses and column K is the amount.
Whenever I execute the Macro, it says "Object Required" but doesn't say which line the error occurred at.
Any ideas? I only started trying out VBA a few days ago and it's probably a newbie mistake.
Upvotes: 0
Views: 907
Reputation:
Nothing is wrong with your code
If Not Worksheets("Fijos") Is Nothing Then
Worksheets("Fijos") cannot = Nothing because when you reference an non-existing member of a collection Error #9 Subscript out of range is thrown.
c.Offset(0, 1) Is Nothing
c.Offset(0, x) will never = Nothing either.
Worksheets is a collection of objects not a single object. Collections use {Key, Value} pairs to store Objects or values. Keys are unique. I you try to add the same key twice to a collection it will throw an error. If you try to retrieve a value for a collection, it will throw an error. Knowing that let's step throw the line of code.
If Not Worksheets("Fijos") Is Nothing Then
- If: If what? Let's compare stuff
- Compare what?
- Not
- Not what?
- Worksheets("Non Existing Key")
- What is Worksheets("Non Existing Key")
- It's a value stored in Worksheets -> Worksheet collection
- What is the value of Worksheets("Non Existing Key")?
- At this point the [in Worksheets -> Worksheet collection] throws the #9 Subscript out of range error.
- Execution stops.
- The second part of the comparison is never reached
- Is Nothing is never evaluated
If you need to know if an item exists in a collection you have to trap the Subscript out of range error.
Function hasWorkBook(WorkbookName As String)
On Error Resume Next
Call Workbooks(WorkbookName).Name
If Err.Number <> 0 Then
hasWorkBook = False
Else
hasWorkBook = True
End If
On Error GoTo 0
End Function
Function hasWorkSheet(xlWorkbook As Workbook, SheetName As String)
On Error Resume Next
Call xlWorkbook.Worksheets(SheetName).Name
If Err.Number <> 0 Then
hasWorkSheet = False
Else
hasWorkSheet = True
End If
On Error GoTo 0
End Function
Upvotes: 0
Reputation:
This line throw an error
ActiveCell.Text = "Tarjeta de Credito"
The text property is read only. It returns the display text of the cell not the cells value.
Use:
ActiveCell.Value = "Tarjeta de Credito"
I refactored your code removing any conditions that couldn't fail and combining the other if statements when possible.
Sub CargarFijos()
ActiveSheet.Range("J4").Activate
If Not IsEmpty(ActiveSheet.Previous.Range("C12")) Then
ActiveCell.Value = "Tarjeta de Credito"
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = ActiveSheet.Previous.Range("C12").Value
ActiveCell.Offset(1, -1).Select
End If
If Not IsEmpty(ActiveCell) Then ActiveCell.Offset(1, 0).Select
For Each c In Worksheets("Fijos").Range("A2:A40").Cells
If Not IsEmpty(c.Offset(0, 1)) And IsEmpty(c.Offset(0, 2)) Then
ActiveCell.Value = c.Text
ActiveCell.Offset(0, 1).Value = c.Offset(0, 1).Value
ActiveCell.Offset(1, 0).Select
Else
ActiveCell.Value = c.Text
ActiveCell.Offset(0, 1).Value = c.Offset(0, 1).Value
c.Offset(0, 2).Value = c.Offset(0, 2).Value - 1
ActiveCell.Offset(1, 0).Select
End If
Next
End Sub
Upvotes: 1