Why is assigning the Value property of cell causing code to end aburptly? - vba

Private Sub FillRow(programCell As Range, storedProgramCell As Range)
Dim counter As Integer
For counter = 3 To 9
Dim cellOffset As Integer
cellOffset = counter - 3
Dim currentStoredCell As Range
Set currentStoredCell = storedProgramCell.Offset(0, cellOffset)
Dim value As String
value = currentStoredCell.value
Dim currentTargetCell As Range
Set currentTargetCell = programCell.Offset(0, cellOffset)
MsgBox currentStoredCell.value 'Works correctly, prints correct value
currentTargetCell.value = value
Next counter
End Sub
The line:
currentTargetCell.value = value
causes the code to stop executing, with no error.
I added the expression to my watch list, then stepped through the routine. The expression was seen as a Boolean:
This makes me think the expression is being viewed as a comparison, and the program abruptly ends since the returned Boolean is not being stored or used anywhere. I wouldn't doubt if I were wrong though.
I'm new to VBA, struggling to debug my program, so please forgive me if this is a petty mistake. I couldn't find any sources online that explains this problem.

Replace your subroutine with following code:
Private Sub FillRow(Dst As Range, Src As Range)
Dim x As Integer
Dim v As Variant
Dim Srcx As Range
Dim Dstx As Range
Debug.Print "FillRow"
Debug.Print Src.Address
Debug.Print Dst.Address
Debug.Print "Loop"
For x = 0 To 6
Debug.Print x
Set Srcx = Src.Offset(0, x)
Debug.Print Srcx.Address
v = Srcx.Value
Debug.Print TypeName(v)
Set Dstx = Dst.Offset(0, x)
Debug.Print Dstx.Address
Dstx.Value = v
Next
Debug.Print "Completed"
End Sub
Run and post in your question Immediate window output.

Value is a reserved word, even if vba does not raise an error on this name, you should not use it. Name it something else. Also, try setting it as a variant.

Related

# VALUE Error while executing UDF VBA Function on formatted cells

I wrote the following function to check if the prerequisites for my Excel row are satisified.
Public Function PREREQUISITESOK(prerequisites As Range) As String
Dim cw As Worksheet
Dim prerequisite_cell As Range
Dim prerequisite_cell_txt As String
Dim training_id_cell As Range
Dim no_groups_cell_to_compare As Range
Dim no_groups_cell_to_check As Range
Dim training_id_cell_txt As String
Dim training_id_cell_row_n As Integer
Dim n As Integer
Application.Volatile
PREREQUISITESOK = "OK"
Set cw = Sheets("4c.Trainings OSS")
Set training_id = cw.Range("$B$11:$B$34")
Set no_groups_cell_to_compare = cw.Range("J" & CStr(prerequisites.Row))
For Each prerequisite_cell In prerequisites.Cells
prerequisite_cell_txt = prerequisite_cell.Text
If prerequisite_cell_txt = "" Then
Exit For
Else
For Each training_id_cell In training_id.Cells
training_id_cell_txt = training_id_cell.Text
If training_id_cell_txt = prerequisite_cell_txt Then
training_id_cell_row_n = training_id_cell.Row
Set no_groups_cell_to_check = cw.Cells(training_id_cell_row_n, no_groups_cell_to_compare.Column)
If no_groups_cell_to_check.Value < no_groups_cell_to_compare.Value Then
PREREQUISITESOK = "NOT OK"
Exit Function 'It is enough for us that one prerequisite is not satisfied so we can exit the function
Else
PREREQUISITESOK = "OK"
End If
Exit For 'Training IDs are unique so if we find the right Training ID then we may exit the loop
End If
Next training_id_cell
End If
Next prerequisite_cell
End Function
Note that the prerequisites range is inline formatted.
The function that I wrote is supposed to return String value so I completely do not understand why am I getting #VALUE! error.
What is interesting that if I clear formatting from the prerequisites cells that are used as arguments of the function then #VALUE! error disappears.
Do you have any idea why this happens?

Compiling error in returning a value

I have a problem:
Public Sub ChangeRow(Column As String, Value As String, id As Integer)
For i = 4 To 15
For Each rw In Worksheets(i).Rows
If Worksheets(i).Range("A" & rw.row).Value = id Then
Dim row As Integer
**row = getRow(id, i)**
MsgBox (row)
If Worksheets(i).Range(Column & rw.row).Value <> Value Then
Worksheets(i).Range(Column & rw.row) = Value
End If
Exit For
End If
Next rw
Next i
End Sub
Function getRow(id As Integer, Sheet As Integer) As Integer
For Each rw In Worksheets(Sheet).Rows
If Worksheets(Sheet).Range("A" & rw.row).Value = id Then
getRow = rw.row
End If
Next rw
End Function
Change Row Works fine... its just when I add 'row = getRow(id, i)' to the mix it throws a ByRef mismatch error??
This is a great example as to why using Option Explicit is a great practice.
Add Option Explicit to the very top of your worksheet module, outside your macro.
This forces you to declare all variables used in your subs, and also can help catch typos in your variable names.
This would catch that i is not declared. What's therefore happening is VBA/Excel by default will set i to be Variant.
Then, when you hit row = getRow(id, i), you're basically passing row = getRow([integer], [Variant]). But that sub is expecting getRow([integer],[integer])...hence your Type Mismatch error.
So, as mentioned, just do Dim i as Integer at the top of the ChangeRow sub.
(or, for long run VBA use Long instead of Integer).
In the function, you need to declare "Sheet" as Worksheet object
Function getRow(id As Integer, Sheet As Worksheet) As Integer

Simple cipher in VBA in Excel using a table for substitution

I want to write a simple cipher in Excel which would take a text from a cell, substitute each letter for a number from adjacent column and then put the output in another cell. Can't get VLOOKUP to work - it works as a formula, but somehow can't get it to work inside VBA code. Tried to do a simple procedure first that would do this for one character (adding a loop later would be easy), but it doesn't work. It compiles, but when I run it (press a button I assigned it to) I get "#N/A" in the result cell.
Sub Zakoduj()
Dim Literka As String
Dim Liczba As Variant
Dim ColumnToTake As Integer
ColumnToTake = 1 ' Liczby
On Error Resume Next
Err.Clear
Literka = Sheets("Sheet2").Range("B2").Value
Liczba = Application.VLookup(Literka, Sheets("Sheet1").Range("A5:B39"), ColumnToTake, False)
If Err.Number = 0 Then
Sheet2.Range("B6").Value = Liczba
Else
Sheet2.Range("B6").Value = Err.Number
End If
End Sub
The range contains number and characters as follows:
Kod Litera
16 A
73 B
12 C
40 D
70 E
etc. etc.
Couldn't find a tutorial that would explain how to do this...
Here is a modified version. Note that the values are in A1:B6 on sheet 1
Option Explicit
Sub Zakoduj()
Dim Literka As Integer
Dim Liczba As String
Dim ColumnToTake As Integer
ColumnToTake = 2 ' Liczby
Literka = Sheets("Sheet2").Range("B2").Value
Liczba = "Value not found" 'If value is not found
On Error Resume Next
Liczba = Application.WorksheetFunction.VLookup(Literka, Sheets("Sheet1").Range("A1:B6"), ColumnToTake, False)
On Error GoTo 0 'Always reset error handling after On Error Resume Next
Sheet2.Range("B6").Value = Liczba
End Sub

Skip iteration of loop if certain value exists

I have the following code below that iterates through rows of a specific range and if a value is present (code not seen), creates copies of the entire pages. My concern is at the bottom of the code in the iteration of r1. It originally only had one conditional statement...
If BiDiRowValid(r1)
and I wanted to add a second conditional statement, which I did...
and Range("MAIN_BIDI_PINMC") <> "No BiDi"
but when I run the code and the MAIN_BIDI_PINMC range = "No BiDi", it errors out and doesn't get past that line. FYI: IsBiDiRowValid() is a function that checks to see that the specific r1 is not empty, and then continues. Right after that subroutine finishes and exits, my code errors with a "Type Mismatch error". I also added the ElseIf line at the bottom, I have not gotten to that code because the top errors out, but I just want to make sure I am writing this iteration correctly, and if anything else needs to be done. Basically, if "NoBiDi" is found in the range, I want it to skip all of this code and go to the next r1... which is what I think I have written... Thanks in advance!
Private Sub start_new()
Dim MC_List As Range
Dim r1 As Range
Dim biDiPinName As Range
Dim Pin As String
Dim mc As String
Dim mType As String
Dim tabName As String
Dim rowNumber As Integer
Dim pinmcSplit() As String
Dim NoBidi As String
On Error GoTo start_biDi_tr_new_Error
Set MC_List = Range("MAIN_PINMC_TABLE")
Set biDiPinName = Range("MAIN_PIN2_NAME")
For Each r1 In MC_List.Rows
If IsBiDiRowValid(r1) And WorksheetFunction.CountIf(Worksheets("MAIN").Range("MAIN_BIDI_PINMC", "No Bidi") = 0 Then
tabName = r1.Cells(1, 8)
pinmcSplit = Split(tabName, "_")
Pin = pinmcSplit(0)
mc = pinmcSplit(1)
mType = r1.Cells(1, 3)
ElseIf WorksheetFunction.CountIf(Worksheets("MAIN").Range("MAIN_BIDI_PINMC"), "No Bidi") = 1 Then
End If
Next
You are getting that error because Range("MAIN_BIDI_PINMC") is not a single cell. To check for a value in multiple cells you can use Application.Worksheetfunction.Countif
EDIT
Post discussion in chat, the user wanted to loop through each cell.
Dim aCell As Range
For Each r1 In MC_List.Rows
If IsBiDiRowValid(r1) Then
For Each aCell In Worksheets("MAIN").Range("MAIN_BIDI_PINMC")
If aCell.Value <> "No Bidi" Then
tabName = r1.Cells(1, 8)
pinmcSplit = Split(tabName, "_")
Pin = pinmcSplit(0)
mc = pinmcSplit(1)
mType = r1.Cells(1, 3)
End If
Next
ElseIf aCell.Value = "No Bidi" Then
'~~> Do Something
End If
Next

VBA Runtime Error 9: Subscript out of range

I have been trying to write a small piece of code to validate to confirm whether or not a date is included in an array. I have been able to scroll through the code until I reach the line If lists(i) = TodaysDate Then when the lists(i) show subscript out of range. I have searched through the Internet and I'm unable to resolve this issue.
My Macro reads as follows:
Sub size_an_array()
Dim i As Integer
Dim Range_of_Dates As Integer
Dim TodaysDate As Variant, finish As String
TodaysDate = Range("Sheet11!c2")
ThisWorkbook.Worksheets("Sheet11").Activate
lists = Range("Processed_Dates")
Range_of_Dates = UBound(lists, 1) - LBound(lists, 1) + 1
For c = 1 To UBound(lists, 1) ' First array dimension is rows.
For R = 1 To UBound(lists, 2) ' Second array dimension is columns.
Debug.Print lists(c, R)
Next R
Next c
x = Range_of_Dates 'UBound(lists, 1)
ReDim lists(x, 1)
i = 1
Do Until i = x
If lists(i) = TodaysDate Then
Exit Do
End If
Loop
MsgBox "The date has not been found"
End Sub
I'm relatively new to VBA and I have been trying to use named ranges to pull in the array but I'm completely at my wits end in trying to solve this piece.
Any help would be greatly appreciated.
You have ReDimmed the array lists from a one dimensioned array to a two dimensioned array and you are then trying to reference an element using only one dimension in the suspect line (below), which is causing your error.
If lists(i) = TodaysDate Then
For reference, Run-time error 9: Subscript out of range means you are referencing a non-existent array element.
I think this is what you are trying?
Sub size_an_array()
Dim i As Integer
Dim TodaysDate As Variant, lists
Dim bFound As Boolean
'~~> Change SomeWorksheet to the relevant sheet
TodaysDate = Sheets("SomeWorksheet").Range("c2")
lists = Sheets("Sheet11").Range("Processed_Dates")
i = 1
Do Until i = UBound(lists)
If lists(i, 1) = TodaysDate Then
bFound = True
Exit Do
End If
i = i + 1
Loop
If bFound = True Then
MsgBox "The date has been found"
Else
MsgBox "The date has not been found"
End If
End Sub
If I understand you correctly then it is much easier to use .Find. If you are interested then have a look at this link.