Vba 将非空白单元格复制到下面的单元格中,对每个空白单元格重复此操作

Vba 将非空白单元格复制到下面的单元格中,对每个空白单元格重复此操作,vba,excel,Vba,Excel,我有一个Excel数据集,在A1中有一个字符串,在B1、B2和B3中有与A1相关的其他值;从这一页往下看。有时,与另一个字符串相关的单元格超过三个(不可预测)。在本例中,单元格A2和A3为空白。我想创建一个宏,用A1的内容填充A2和A3(等等) 在下面的示例中,我使用[]帮助将其格式化为Excel单元格。我想从: [SMITH, John] [Home] [Mobile] [Work] [DOE, John] [Home]

我有一个Excel数据集,在A1中有一个字符串,在B1、B2和B3中有与A1相关的其他值;从这一页往下看。有时,与另一个字符串相关的单元格超过三个(不可预测)。在本例中,单元格A2和A3为空白。我想创建一个宏,用A1的内容填充A2和A3(等等)

在下面的示例中,我使用[]帮助将其格式化为Excel单元格。我想从:

[SMITH, John]  [Home]
               [Mobile]
               [Work]
[DOE, John]    [Home]
               [Mobile]

我希望宏在不同的迭代中重复此操作,有时我需要手动调整1000行。调整输出数据的软件不是一个选项


我的守则如下:

Sub rname()
Dim cellvar As String
Dim i As Integer

cellvar = ActiveCell
i = 0

While i < 50
If ActiveCell.Offset(1,0) = "" Then
ActiveCell.Offset(1,0) = cellvar
i = i + 1

ElseIf ActiveCell.Offset(1,0) = "*" Then
ActiveCell.Offset(1,0).Activate
i = i + 1

End If
Wend
End Sub
我被难住了。有人有什么想法或建议吗?

试试这个:

Sub repeat_name()

Dim cellvar As String
Dim i As Integer
Dim ws As Worksheet

Set ws = Sheet1    'Change according to your sheet number
cellvar = ""
For i = 1 To 50

if Trim(ws.Range("A" & i )) <> "" then
 cellvar = Trim(ws.Range("A" & i ))
Else
 ws.Range("A" & i ) = cellvar
End if

Next i

End Sub
Sub repeat_name()
作为字符串的Dim cellvar
作为整数的Dim i
将ws设置为工作表
设置ws=Sheet1'根据图纸编号进行更改
cellvar=“”
对于i=1到50
如果修剪(ws.Range(“A”&i))“”则
cellvar=微调(宽度范围(“A”和“i”)
其他的
ws.Range(“A”&i)=cellvar
如果结束
接下来我
端接头
试试看

Sub fillBlanks()
    With Worksheets("Sheet1")
        With .Range(.Cells(2, "B"), .Cells(Rows.Count, "B").End(xlUp))
            With .Offset(0, -1).SpecialCells(xlCellTypeBlanks)
                .FormulaR1C1 = "=R[-1]C"
            End With
            With .Offset(0, -1)
                .Value = .Value
            End With
        End With
    End With
End Sub

在Fillbanks程序之前,在Fillbanks程序之后

Sub FillBlanks()
    Columns("A:A").Select
    Selection.SpecialCells(xlCellTypeBlanks).Select
    Selection.FormulaR1C1 = "=R[-1]C"
End Sub
试试这个:

Sub repeat_name()

Dim k As Integer
Dim i As Integer

i = 1
k = ActiveSheet.UsedRange.Rows.Count

While i <= k
    With ActiveSheet
        If .Range("A1").Value = "" Then
            MsgBox "Error: First cell can not be empty."
            Exit Sub
        End If
        If .Range("A" & i).Value = "" And .Range("B" & i).Value <> "" Then
            .Range("A" & i).Value = .Range("A" & i - 1).Value
        End If
    End With
    i = i + 1
Wend

End Sub
Sub repeat_name()
将k变为整数
作为整数的Dim i
i=1
k=ActiveSheet.UsedRange.Rows.Count
而我试试这个

Sub test()
lastrow = Range("B" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
    If Cells(i, 1) = "" Then
        Cells(i, 1) = Cells(i - 1, 1)
    End If
Next i
End Sub

其他人已经给出了有效的解决方案,我将仅概述代码中的问题

cellvar=ActiveCell
将活动单元格的值指定给cellvar,但如果ActiveCell发生更改,cellvar不会更改,因此您只需为所有其他人复制[SMITH,John]。你必须重新分配cellvar

如果ActiveCell.Offset(1,0)=“*”则检查单元格是否包含星号。相反,请使用
非ActiveCell.Offset(1,0)=“
ActiveCell.Offset(1,0)”,
非空(ActiveCell.Offset(1,0))
或仅使用
Else
(这将是此处的首选版本,因为它不需要进一步计算)

编辑:
“*”
可以与
中的
Like
运算符一起用作通配符,如果ActiveCell.Offset(1,0)Like“*”则为
,但对于空字符串也是如此。为了确保至少有一个符号,您必须使用
“?*”
。问号表示一个字符,星号表示0或更多。要检查单元格是否为空,我建议使用上述方法之一

在您的第一个子单元中,这意味着如果单元格中除“*”以外的任何内容,我将不会递增,而您将以一个无止境的循环结束。在第二个函数中,这意味着不会更改活动单元的值,并且对于循环的其余部分,也不会检测到“not”*

在第二个子循环中,您不需要
i=i+1
,for
循环会为您做这件事。这意味着每次迭代都要将i增加2

ActiveCell.Offset(1,0)。Select.Activate
这里的“Select”太多了

以下是改动最小的潜艇:

Sub rname()
    Dim cellvar As String
    Dim i As Integer

    cellvar = ActiveCell
    i = 0

    While i < 50
        If ActiveCell.Offset(1, 0) = "" Then
            ActiveCell.Offset(1, 0) = cellvar
            ActiveCell.Offset(1, 0).Activate 'the code will run without this but need to iterations per row
            i = i + 1
            MsgBox "a " & i

        Else
            ActiveCell.Offset(1, 0).Activate
            cellvar = ActiveCell        'reassign cellvar
            i = i + 1
            MsgBox "b " & i
        End If

    Wend
End Sub

请注意,这只是为了解释代码中的问题,我仍然建议在这里使用其他解决方案之一。

Perfect。用不同的方法做我想要的事情。非常清楚如何在数据不在下一列时对其进行调整。代码很整洁,为了理解它,我需要研究一些东西。您好,非常感谢您花时间解释。我在某个地方遇到的一个例子被视为一个通配符,所以我很高兴知道我偏离了方向(可能是浏览得太快了)。我明白你说的cellvar没有被正确分配是什么意思,这对我来说是一个非常愚蠢的错误。再次感谢你抽出时间来教育我那里的一切;这让我意识到,我需要更仔细地思考每一行实现了什么以及如何实现。嗨,你对通配符的看法是正确的,尽管它显然不能用于
=
比较(或strComp)。它与
类似
操作符一起工作。“*”仍然是错误的选择(见我编辑的帖子)。
Sub test()
lastrow = Range("B" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
    If Cells(i, 1) = "" Then
        Cells(i, 1) = Cells(i - 1, 1)
    End If
Next i
End Sub
Sub rname()
    Dim cellvar As String
    Dim i As Integer

    cellvar = ActiveCell
    i = 0

    While i < 50
        If ActiveCell.Offset(1, 0) = "" Then
            ActiveCell.Offset(1, 0) = cellvar
            ActiveCell.Offset(1, 0).Activate 'the code will run without this but need to iterations per row
            i = i + 1
            MsgBox "a " & i

        Else
            ActiveCell.Offset(1, 0).Activate
            cellvar = ActiveCell        'reassign cellvar
            i = i + 1
            MsgBox "b " & i
        End If

    Wend
End Sub
Sub repeat_name()

    Dim cellvar As String
    Dim i As Integer

    cellvar = ActiveCell
    'i = 1 'this is not necessary

    For i = 1 To 50

        If ActiveCell.Offset(1, 0) = "" Then
            ActiveCell.Offset(1, 0) = cellvar
        End If

        If Not ActiveCell.Offset(1, 0) = "" Then    'if else endif would be nicer here
            ActiveCell.Offset(1, 0).Activate        'remove "select"
            cellvar = ActiveCell    'reassign cellvar
        End If

        'i = i + 1 'this is not necessary/wrong
    Next i      'safer to include i

End Sub