2

I'm making a VBA macro to concatenate a number given by the user with a previous column value. Once the loop gets to the value given by the user (the top value), the loop would start again since number one. By now my loop gets to the top value and starts from one, but every time this happened the code skip to the next cell, could you tell me why is this happening guys? (down value by default).

Sorry i'm a little bit new on VBA, here is my try:

Sub Balance()
    Dim myValue As Integer
    myValue = InputBox("Please, give me a number")
    Range("A2").Select
    Range("A:A,C:C,F:F,H:J,L:L,T:T,W:X").Delete
    Range("A2").Select
    firstrow = ActiveCell.Row
    Selection.End(xlDown).Select
    lastrow = ActiveCell.Row
    For i = 1 To lastrow
        If Range("M" & i) = "AB" Then
            For j = 1 To myValue
                watcher = j
                Range("N" & i) = "TV" & " " & Range("M" & i) & " " & watcher
                i = i + 1
            Next j
        End If
    Next i
End Sub

This the output with the number 10 as input (Column N):

enter image description here

I would like to reach this goal:

enter image description here

Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
Xkid
  • 338
  • 1
  • 4
  • 17

2 Answers2

1

You already have your answer by Vandear explaining why the row is getting skipped. However here is an alternative way using only one loop to achieve what you want. But before that couple of suggestions

Suggestions:

  1. Use Option Explicit and declare your variables. You may want to see Optimizing the VBA Code and improve the performance
  2. Avoid the use of Select/Activate You may want to see How to avoid using Select in Excel VBA
  3. Avoid the use of xlDown to get the last row. You may want to see Finding Last Row
  4. When accepting number from users, use Application.InputBox with a Type:=1 instead of just InputBox. This way you will only restrict numbers.

Is this what you are trying?

Code:

Option Explicit

Sub Balance()
    Dim ws As Worksheet
    Dim lRow As Long
    Dim i As Long, counter As Long
    Dim myValue As Long
  
    myValue = Application.InputBox(Prompt:="Please, give me a number", Type:=1)
  
    If myValue < 1 Then Exit Sub
  
    '~~> Change this to the relevant sheet
    Set ws = Sheet1
  
    With ws
        '~~> For demonstration below. I did not use this line below. But
        '~~> If you need to delete those columns then use it this way
        .Range("A:A,C:C,F:F,H:J,L:L,T:T,W:X").Delete

        lRow = .Range("A" & .Rows.Count).End(xlUp).Row
        
        '~~> Set your counter
        counter = 1
        
        For i = 1 To lRow
            If .Range("M" & i) = "AB" Then
                Range("N" & i) = "TV" & " " & .Range("M" & i).Value2 & " " & counter
                counter = counter + 1
                '~~> Reset your counter if it crosses user input
                If counter > myValue Then counter = 1
            End If
        Next i
    End With
End Sub

In action:

enter image description here

Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
  • Thanks a lot for your help, your solution works perfectly! I'll take your advices to improve my code. – Xkid Jan 08 '21 at 19:20
0

Couple of things before I answer your problem:

  1. It's advisable to declare your variables for better structure:
Dim i As Integer, j As Integer, MyValue As Integer, firstrow As Integer, lastrow As Integer
  1. You can skip the selection of a cell and directly reference it:

    firstrow = Range("A2").Row
    lastrow = Range("A2").End(xlDown).Row

The Answer to your Problem:

When the code exits the for-next loop for j, i is increased by 1 (i=i+1), and then it will be increased again by 1 when it proceeds to the next i line. This is the reason why it skips to the next row. So after the for-next loop for j, you need to decrease i by 1 before proceeding to the for-next loop for i.

For i = 1 To lastrow
    If Range("M" & i) = "AB" Then
      For j = 1 To myValue
      watcher = j
      Range("N" & i) = "TV" & " " & Range("M" & i) & " " & watcher
      i = i + 1
      Next j
      i=i-1  <-------
    End If
Next i
vk26
  • 85
  • 8
  • **1.** Whenever working with rows, do not work with `Integer`. Work with `Long`. **2.** Avoid the use of `xlDown` to get the last row. You may want to see [Finding Last Row](https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba) – Siddharth Rout Jan 08 '21 at 06:38