【问题标题】:Excel VBA Macros Format rows based on ValuesExcel VBA 宏根据值格式化行
【发布时间】:2015-01-23 11:20:35
【问题描述】:

大家好,我有一张表格,我想用 vba 格式化,因为它有很多值,而且一个一个格式化需要很长时间。

例子

客户 ID ---------- 员工 ---------- 工作时间

0001 ------------------乔什 -------------5

0001 ------------------卡尔 -------------5

0001 ------------------乔 --------------5

0005 ------------------肯 --------------5

0005 ------------------杰夫 --------------5

0008 ------------------乔 --------------5

0008 ------------------乔什 -------------5

0009 ------------------卡尔 -------------5

0011 ------------------乔 --------------5

0011 ------------------卡尔 --------------5

我想在同一个 ClientID 的最后一个下方应用一个边框,以将它们与 ClientID 的其余部分分开,以便在查看信息时更容易阅读,因此输出应该是这样的:

客户 ID ---------- 员工 ---------- 工作时间

0001 ------------------乔什 -------------5

0001 ------------------卡尔 -------------5

0001 ------------------乔 --------------5


0005 ------------------肯 --------------5

0005 ------------------杰夫 --------------5


0008 ------------------乔 --------------5

0008 ------------------乔什 -------------5


0009 ------------------卡尔 -------------5


0011 ------------------乔 --------------5

0011 ------------------卡尔 --------------5


我猜我需要某种循环来向下 ClientID 列并检查每个 ClientID..一旦出现新的 ClientID 然后在该行的顶部或前一行的底部添加一个边框。我知道我应该有一些代码,如果有人能指出我正确的方向或给我一些线索,我可以继续写一些东西。

【问题讨论】:

  • 您需要使用 VBA 还是可以使用条件格式?
  • 我需要使用 VBA/宏,因为行数太多,无法一一完成或为几列编写公式。基本上我想创建一个有人运行的模块并应用该格式。
  • 数据是否已经按客户端 ID 排序,还是需要先排序?
  • 数据已经从低到高排序了。
  • 标题在第 1 行,从第 1 行下方的 A 开始是数据。与您在屏幕截图中发布的相同,但有更多列包含更多信息。这很奇怪,因为当我将表格复制到单独的工作表中并运行代码时,它可以工作,但不能在原始工作表中工作。我在上面的原始问题中添加了我的工作表的屏幕截图

标签: vba excel


【解决方案1】:

如果你有如下图格式的数据:

然后下面的宏将在客户端 ID 更改时添加边框。此宏假定客户端 ID 已按升序或降序排序。

宏

Sub border()
'Macro valid & comments valid for Excel 2007 or greater

'Dimensions all the initial variables; it is good practice to declare all your variables at top and to capitalize one letter so that when VBA interprets the variable when you exit the row, it will automatically make the variable uppercase and you know you spelled it correctly

'variable for current row number when looping through all the data
Dim Ro As Integer
'variable for the maximum number of rows in the dataset
Dim mRo As Integer
'variable for the maximum number of columns in the dataset
Dim mCo As Integer

    'selects the first sheet in the active workbook to use as the parent object for all code contained in the WITH statement.  VBA is object oriented meaning there are a lot of parent-child relationships.  In this case, all the code inside the WITH statement is the parent, or containing object, and the internal code are the children objects
    With Sheets(1)
        'Determines last row in the range of all data
        'Uses .Rows.Count to find the last row in Excel (1,048,576 for Excel 2007+) and then goes all the way up (xlUp) until it hits a "different" type of cell.  Almost 99.9999% of the time, row 1,048,576 will be blank, so this will traverse up until it reaches the first non-blank row, or the bottom of our dataset.  This is similar to starting out at A1048576 and pressing Ctrl+Up Arrow
        mRo = .Cells(.Rows.Count, 1).End(xlUp).Row
        'Same action as the row, but goes to the left until it reaches non-blank data
        mCo = .Cells(1, .Columns.Count).End(xlToLeft).Column

        'Removes borders from original table
        .Range(.Cells(1, 1), .Cells(mRo, mCo)).Borders.LineStyle = xlNone            

        'loops through data to compare when a Client ID changes
        'Starts are row 2 and performs a for loop until it reaches the end of the dataset at the mRo row
        For Ro = 2 To mRo
            'Checks to see if the client ID changes & applies a border
            'Looks to see if the row below (Ro + 1) in the first column (Client ID) is different from the current row's (Ro) first column.  If there is a difference, then the Client ID just changed and we want to add a border
            If .Cells(Ro, 1).Value <> .Cells(Ro + 1, 1).Value Then
                'Adds border to bottom of rows
                'The range is selected from the current row (Ro) first column to the current row (Ro) last column (mCo).  The formatting of the border was actually determined from using the VBA "Record Macro" function (if you don't see "Developer" in your ribbon bar, click on either FILE or the Office symbol in the upper left hand corner of Excel, go to OPTIONS, CUSTOMIZE RIBBON and check the DEVELOPER checkbox on the right hand side.  Then, you will see the DEVELOPER tab in the ribbon bar and you can use the "Record Macro" feature
                With .Range(.Cells(ro, 1), .Cells(ro, mCo)).Borders(xlEdgeBottom)
                    .LineStyle = xlContinuous
                    .Weight = xlThick
                End With
            End If
        Next
    End With
End Sub

结果

【讨论】:

  • 我会测试一下 :) 你碰巧有一些用于文档和实现的网站吗?我喜欢阅读它们,以便了解它的工作原理并学习它:)
  • 这里一点点,那里一点点。我将添加更多的 cmets,以便您能够更好地理解它。
  • 我测试了它,一切似乎都正确,但我得到运行时错误'1004':对象_工作表的方法范围失败
  • 您是否认为这是因为代码的 With Sheets(1) 部分可能指向错误的工作表...我拥有的工作表名为 FinalReport 但是当我调试时它指向 Range (.Cells(ro, 1), .Cells(ro, mCo)).Borders(xlEdgeBottom).LineStyle = xlContinuous 是代码的一部分不起作用...如果我应该更改 With Sheets("FinalReport") 哪个我做到了,但我没有收到任何错误,但它什么也没做
  • 实际excel表格中的“FinalReport”是哪个顺序?
【解决方案2】:

使用条件格式公式规则:

=$A1<>$A2  

应用于 A:C,或者可能通过添加一个空白行作为分隔符(例如在每次更改客户 ID 时使用小计 - 然后可以将其更改为边框)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 2013-08-10
    相关资源
    最近更新 更多