2012-09-16 49 views
0

我是一个完整的excel初学者,今天得到了一份任务,明天就可以完成。如果有人能帮助我,我会很感激。 我有具有下表的片材:Excel VBA编程

enter image description here

第一张表是主,从中我需要得到的数据,并表示它使用的Marco-VBA单独的表的形式。将不胜感激任何帮助,以实现这个使用宏。谢谢。

假设主表有n列,所以我需要形成n-1个独立的表,其中每个表将有2列,第一列将始终是主表的第一列,第二列将是(n +1)列从第n个表的主表中删除。示例 - 第一个表将有2列(主表的第1列和主表的第2列),同样,第2表将有2列(主表的第1列和主表的第3列),等等。 ..

+0

你今天没有收到这份作业! – JMK

+0

今天知道了,我很无奈,是一个J2EE人:P – NINCOMPOOP

+0

啊,假设你是一个学生,道歉! – JMK

回答

4

我会在接下来的一个小时左右添加到这个答案。当我开发后面的块时,这个想法就是让你从早期的代码块开始。 编辑我现在已经完成了答案,除了您可能寻求的任何额外解释。

我同意RBarryYoung:你没有提供足够的信息让任何人为你提供一个完整的解决方案。另外,如果您正在尝试学习VBA,那么从长远来看,给您提供解决方案将无济于事。

我通常会同意djphatic:宏记录器对于学习与用户操作相匹配的VBA非常有用,但宏记录器不会给你很多这个任务所需的VBA。

我很好奇谁给你这个任务,当你显然没有准备好。

我看不懂你的形象,所以我创建了一个工作,我命名为“MasterTable”,并与数据加载它,所以它看起来像:

Sample data

您的评论暗示,这个表的大小可能会改变,因此首要任务是确定其尺寸。确定表格尺寸的方法有很多种,在任何情况下都不适用。我将使用UsedRange。

复制以下到模块:

Option Explicit 
Sub SplitTable1() 

    Dim UsedRng As Range 

    With Worksheets("MasterTable") 

    Set UsedRng = .UsedRange 
    Debug.Print UsedRng.Address 
    Debug.Print UsedRng.Columns.Count 
    Debug.Print UsedRng.Rows.Count 

    End With 

End Sub 

没有时间付出一切的完整的解释,我会告诉你,但我会尽量解释最重要的一点。

Option Explicit表示必须声明每个变量。没有这个声明,拼写错误名称将自动声明一个新变量。

Debug.Print将值输出到立即窗口,该窗口应该在VBA编辑器屏幕的底部。如果不存在,请点击Ctrl + G

Dim UsedRng As Range声明类型为Range的变量UsedRng。范围是一种对象。当你给一个对象赋值时,你必须用Set开始声明。

运行此宏会输出如下立即窗口:

$A$1:$H$6 
8 
6 

我不会使用UsedRng.AddressUsedRng.Columns.Count,但我希望你明白UsedRange是什么以及它如何被使用。

该宏添加到模块:

Sub SplitTable2() 

    Dim CellValue() As Variant 
    Dim ColCrnt As Long 
    Dim RowCrnt As Long 

    With Worksheets("MasterTable") 

    CellValue = .UsedRange.Value 

    For RowCrnt = LBound(CellValue, 1) To UBound(CellValue, 1) 
    Debug.Print "Row " & RowCrnt & ":"; 
    For ColCrnt = LBound(CellValue, 2) To UBound(CellValue, 2) 
     Debug.Print " " & CellValue(RowCrnt, ColCrnt); 
    Next 
    Debug.Print 
    Next 

    End With 

End Sub 

Dim CellValue() As Variant声明了一个动态数组,CellValue,Variant类型。 ()意味着我将在运行时声明数组的大小。

CellValue = .UsedRange.Value将数组CellValue设置为UserRange中的值。该语句根据需要设置CellValue的尺寸。

CellValue成为二维阵列。通常,数组的第一个维度是列,第二个维度是行,但是当数组从一个范围加载或到一个范围时,这不是TRUE。

使用一维数组,LBound(MyArray)返回数组的下限,UBound(MyArray)返回上限。

使用二维数组,LBound(MyArray, 1)返回数组第一维的下界,LBound(MyArray, 2)返回第二维的下界。

该宏将以下内容输出到立即窗口。

Row 1: Column 1 Column 2 Column 3 Column 4 Column 5 Column 6 Column 7 Column 8 
Row 2: R1C1 R1C2 R1C3 R1C4 R1C5 R1C6 R1C7 R1C8 
Row 3: R2C1 R2C2 R2C3 R2C4 R2C5 R2C6 R2C7 R2C8 
Row 4: R3C1 R3C2 R3C3 R3C4 R3C5 R3C6 R3C7 R3C8 
Row 5: R4C1 R4C2 R4C3 R4C4 R4C5 R4C6 R4C7 R4C8 
Row 6: R5C1 R5C2 R5C3 R5C4 R5C5 R5C6 R5C7 R5C8 

第二个宏说明我可以将工作表中的所有值加载到数组中,然后输出它们。

这个宏添加到模块:

Sub SplitTable3() 

    Dim ColourBack As Long 
    Dim ColourFont As Long 

    With Worksheets("MasterTable") 
    ColourBack = .Range("A1").Interior.Color 
    ColourFont = .Range("A1").Font.Color 
    Debug.Print ColourBack 
    Debug.Print ColourFont 
    End With 

End Sub 

运行这个宏,它会输出:

16711680 
16777215 

对于这个答案,这些都只是幻数。 16777215将字体颜色设置为白色,并且16711680将背景或内部颜色设置为蓝色。

对于最后一个宏,我创建了另一个工作表“SplitTables”。

这个宏添加到模块:

Sub SplitTable4() 

    Dim CellValue() As Variant 
    Dim ColDestCrnt As Long 
    Dim ColourBack As Long 
    Dim ColourFont As Long 
    Dim ColSrcCrnt As Long 
    Dim RowDestCrnt As Long 
    Dim RowDestStart As Long 
    Dim RowSrcCrnt As Long 

    With Worksheets("MasterTable") 
    ' Load required values from worksheet MasterTable 
    CellValue = .UsedRange.Value 
    With .Cells(.UsedRange.Row, .UsedRange.Column) 
     ' Save the values from the top left cell of the used range. 
     ' This allows for the used range being in the middle of the worksheet. 
     ColourBack = .Interior.Color 
     ColourFont = .Font.Color 
    End With 
    End With 

    With Worksheets("SplitTables") 

    ' Delete any existing contents of the worksheet 
    .Cells.EntireRow.Delete 

    ' For this macro I need different variables for the source and destination 
    ' columns. I do not need different variables for the source and destination 
    ' rows but I have coded the macro as though I did. This would allow the 
    ' UsedRange in worksheet "MasterTable" to be in the middle of the worksheet 
    ' and would allow the destination range to be anywhere within worksheet 
    ' "SpltTables". 

    ' Specify the first row and column of the first sub table. You will 
    ' probably want these both to be 1 for cell A1 but I want to show that my 
    ' code will work if you want to start in the middle of the worksheet. 
    ColDestCrnt = 2 
    RowDestStart = 3 

    ' I use LBound when I do not need to because I like to be absolutely 
    ' explicit about what I am doing. An array loaded from a range will 
    ' always have lower bounds of one. 

    For ColSrcCrnt = LBound(CellValue, 2) + 1 To UBound(CellValue, 2) 
     ' Create one sub table from every column after the first. 

     'Duplicate the colours of the header row in worksheet "MasterTable" 
     With .Cells(RowDestStart, ColDestCrnt) 
     .Interior.Color = ColourBack 
     .Font.Color = ColourFont 
     End With 
     With .Cells(RowDestStart, ColDestCrnt + 1) 
     .Interior.Color = ColourBack 
     .Font.Color = ColourFont 
     End With 

     RowDestCrnt = RowDestStart 

     For RowSrcCrnt = LBound(CellValue, 1) To UBound(CellValue, 1) 
     ' For each row in CellValue, copy the values from the first and current 
     ' columns to the sub table within worksheet "SplitTables" 
     .Cells(RowDestCrnt, ColDestCrnt).Value = _ 
            CellValue(RowSrcCrnt, LBound(CellValue, 2)) 
     .Cells(RowDestCrnt, ColDestCrnt + 1).Value = _ 
               CellValue(RowSrcCrnt, ColSrcCrnt) 
     RowDestCrnt = RowDestCrnt + 1 
     Next RowSrcCrnt 
     ColDestCrnt = ColDestCrnt + 3  ' Advance to position of next sub table 
    Next ColSrcCrnt 

    End With 

End Sub 

这才是真正的宏。所有以前的宏都有助于展示一些东西。这个宏做我想要的东西。

回来的问题。但是,我不知道你在什么时区。现在是23点。我将在大约一小时内睡觉。之后,问题将在明天回答。

+0

感谢您的解释! – NINCOMPOOP

+0

非常感谢主席先生,即使在今天当我看到这个解释时,我也敬畏!非常感谢你,先生:) – NINCOMPOOP

+1

@新白痴。我很高兴你仍然发现我的答案有用。尽管现在已经有11年了,但我还记得我刚开始使用VBA时感到的困惑。有了答案,我试着解释我发现的难点。 –

1

看看Excel中的宏记录器。您希望实现的目标看起来像使用VBA在表中的特定列上执行简单的复制和粘贴。如果打开宏记录器并通过复制并粘贴变量并估计列来生成第一个表格,然后点击停止,则可以通过查看Visual Basic编辑器(Ctrl + F11)查看生成的代码。

您可能会发现一些使用这些链接: http://www.automateexcel.com/2004/08/18/excel_cut_copy_paste_from_a_macro/ http://www.techrepublic.com/blog/10things/10-ways-to-reference-excel-workbooks-and-sheets-using-vba/ 967

+0

谢谢。但如果表格是动态的,比如说n * m行数*列!然后 ! – NINCOMPOOP

+0

对于动态行数,您可以使用OFFSET函数使用命名范围。动态列更加困难,因为在上面您希望每个表的特定结果。过去我曾经创建过一些用户从主表中选择他们需要的列,然后VBA获得了列名列表并通过主表循环以复制适当的列。 – mheptinstall