I am working on a macro that copies the cell values available in columns J, K, M and N in columns F and G below the first cell value depending on the case, the macro I have is the one shown below and which I execute by means of a button named "VH"
Sub InsertarDato()
Dim Celda As Range
Dim UltimaFila As Long, x As Long
Dim Valores(1 To 4) As Integer
Let UltimaFila = Cells(Rows.Count, 10).End(xlUp).Row
Valores(1) = 0: Valores(2) = 1: Valores(3) = 3: Valores(4) = 4
For Each Celda In Range("J3:J" & UltimaFila)
For x = 1 To 4
If Celda.Offset(0, Valores(x)) <> "" Or Celda.Offset(0, Valores(x)) <> 0 Then
If Valores(x) = 0 Or Valores(x) = 1 Then
Celda.Offset(Valores(x) + 1, -4).Formula = "=" & Celda.Offset(0, Valores(x)).Address(0, 0)
Else
Celda.Offset(Valores(x) - 2, -3).Formula = "=" & Celda.Offset(0, Valores(x)).Address(0, 0)
End If
End If
Next x
Next Celda
End Sub
The table before executing the macro is shown in this image:
But when I run the macro it doesn't turn out as I expect and it looks like this:
instead of like this which is what I expect when executing the code:
What can I do to make the code work for me? since according to what I have tried where it gives an error is in case 2, since it copies the values in cells without available space, I have tried to add a condition to the macro with additional if
or elseif
but I have not succeeded or rather I do not know how to do it I would appreciate your help in this situation if possible.
Below I describe the cases that the macro must meet in the conditions,
Case 1 : *When cells in columns J and K have a record, they should be copied to column F in the available spaces below the cell with value; For example, if cells J3 and K3 have a numeric value, the cell value must be copied to cells F4 and F5, respectively. *When cells in columns M and N have a record, they must be copied to column G in the available spaces below the cell with value; For example, if cells M3 and N3 have a numeric value, the cell value must be copied to cells G4 and G5, respectively.
Case 2 : *When the cell of columns K has a record, they should be copied to column F in the space available below the cell with value; For example, if cells K6 have a numeric value, the cell value must be copied to cell F7. *When the cell in column N has a record, it should be copied to column G in the available space below the cell with value; For example, if cell N6 has a numeric value, the cell value must be copied to cell G7.
Case 3 : *When the cell of columns J has a record, they should be copied to column F in the space available below the cell with value; For example, if cells J8 have a numeric value, the cell value must be copied to cell F9. *When the cell in column M has a record, it should be copied to column G in the available space below the cell with value; For example, if cell M8 has a numeric value, the cell value must be copied to cell G9.
Case 4 : When the cells of columns J, K, M, and N have values equal to "0" or " ", the macro should not copy values, it should skip and continue evaluating cases 1, 2 and 3.
IMPORTANT : There will always be the necessary spaces available to copy and pay the cell values in all cases since that is another macro that I execute before.
I also share the drive of the file I am working on https://drive.google.com/file/d/1L-c0zrLz4U5S6RNFjMl27RK0fXOSHZr-/view?usp=sharing
I share the macro that I was working with @gbianchi
Sub InsertarDatos()
Let UltimaFila = Cells(Rows.Count, 4).End(xlUp).Row
Dim i
i = 3
Do While (i < UltimaFila)
''caso 1
If (Range("J" & i).Value <> "" And Range("K" & i).Value <> "") Then
''aca copiamos los valores segun corresponde, a las celdas que queremos
Range("F" & (i + 1)).Value = "=" & Range("J" & i).Address
Range("F" & (i + 2)).Value = "=" & Range("K" & i).Address
Range("G" & (i + 1)).Value = "=" & Range("M" & i).Address
Range("G" & (i + 2)).Value = "=" & Range("N" & i).Address
'..si hay mas copias...
''y ahora, aumentamos i a la siguiente linea a procesar
i = i + 3
''caso 2
ElseIf (Range("K" & i).Value <> "") Then
Range("F" & (i + 1)).Value = "=" & Range("K" & i).Address
Range("G" & (i + 1)).Value = "=" & Range("N" & i).Address
'.... hacemos las copias..
''aumentamos i
i = i + 2
''caso 3
ElseIf (Range("J" & i).Value <> "") Then
Range("F" & (i + 1)).Value = "=" & Range("J" & i).Address
Range("G" & (i + 1)).Value = "=" & Range("M" & i).Address
'.... hacemos las copias...
''aumentamos i
i = i + 2
''caso 4
Else
End If
Loop
End Sub
Let's totally change the logic of your process to clearly understand what to do in each case...
First, instead of iterating a range, since there are rows that are not processed, we are going to do the following:
Now, inside the while, let's check each of the conditions, in order...
Note that I wrote you the logic that you have to use for each case... try it, follow it and anything we update the answer.
Your fundamental problem is to identify when it is case 1, 2, 3 or 4. But luckily, you have identified each case in the last column.
The macro should read that column, and depending on whether it is 1, 2, 3 or 4, proceed one way or another.
The downside is that those cells are merged. When the cells are combined, only the first of the set has a value, the others are actually empty. So you have to access the combined area (
MergeArea
) and within that area, always study the first cell, which is the one with the value (the first cell of a range is alwaysCells(1,1)
Knowing this, I have designed a code that does each case individually. If he sees that a merged area has already been surveyed, he ignores it and moves on to the next row.
Here is how it works:
And the code:
UPDATE: Since the P column cannot be used, what I have done is try to establish a mathematical relationship between the IDs and the cases.
If you look, according to your example, the IDs that are repeated 3 times are case 1. Those that are repeated 1 time are case 4. And those that are repeated 2 times can be case 2 or 3, depending on whether the columns J and M are empty or not.
On that mathematical basis, I have modified the original code. What has been done has been to incorporate a dictionary.
With this object, I can store unique values and assign a value to them. That is, I am pointing to each of the IDs in column C, and assigning them if they are Case 1, 2, etc.
Then it's pretty much the same loop as before. This is the code:
try with
Let LastRow = Cells(Rows.Count, 10).End(xlUp).Row dim i i = 3 Do while (i < LastRow)
'Here are the conditional cases that @gbianchi gives you
loop