使用Excel VBA添加表格

huangapple go评论74阅读模式
英文:

Adding Tables using Excel VBA

问题

我想要在这些新工作表中添加新工作表和表格,并使用vba。如下图所示,有两列主类别子类别。我想为每个主类别创建新工作表,并根据它所属的工作表添加表格。此外,我可能会向主类别子类别添加新条目vba代码应该为这些也添加工作表和表格。

Sub CreateSheetsFromAList()
    ' 代码部分不要翻译
End Sub

Function SheetExists(shtName As String, Optional wb As Workbook) As Boolean
    ' 代码部分不要翻译
End Function

Public Sub ChooseSheet(ByVal SheetName As String)
    ' 代码部分不要翻译
End Sub

最终结果如下图所示:

使用Excel VBA添加表格

这是我的示例工作簿,没有任何代码:链接

英文:

I want to add new sheets and add tables in these new sheets, using vba. As shown in the image below, there are two column Main Category and Sub Category. I want to create new sheet for every Main Category and add tables for every Sub Category based on the sheet it belongs to. Additionally I may add new entries to Main Category and Sub Category, the vba code should add sheet and tables for those as well.
<br><br>使用Excel VBA添加表格
<hr>
So far I am able to add the new sheets , but couldn't add the tables , This is what I have:

    Sub CreateSheetsFromAList()
        Dim MyCell As Range, myRange As Range
        Dim MyCell1 As Range, myRange1 As Range
        Dim WSname As String
                
        Sheet1.Select
        Range(&quot;A2&quot;).Select
        Range(ActiveCell, ActiveCell.End(xlDown)).Select
        Set myRange = Selection
        Application.ScreenUpdating = False
        
         For Each MyCell In myRange
            If Len(MyCell.Text) &gt; 0 Then
                &#39;Check if sheet exists
                If Not SheetExists(MyCell.Value) Then
                
                    &#39;run new reports code until before Else
                    
                    Sheets.Add After:=Sheets(Sheets.Count) &#39;creates a new worksheet
                    Sheets(Sheets.Count).Name = MyCell.Value &#39; renames the new worksheet
                                    
                    WSname = MyCell.Value &#39;stores newly created sheetname to a string variable
                   
                    &#39;filters consolidated sheet based on newly created sheetname
                    Sheet3.Select
                    Range(&quot;A:T&quot;).AutoFilter
                    Range(&quot;D1&quot;).Select
                    Range(&quot;D1&quot;).AutoFilter Field:=4, Criteria1:=WSname, Operator:=xlFilterValues
                    
                    Range(&quot;A1:U1&quot;).Select
                    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
                    Range(&quot;A1:U&quot; &amp; lastRow).Select
                    Selection.Copy &#39;copies filtered data
                    
                    &#39;search and activate WSname
                    ChooseSheet WSname
                    
                    Range(&quot;AH2&quot;).Select
                    ActiveCell.PasteSpecial xlPasteValues
                    
                    Range(&quot;AJ:AJ&quot;).Select
                    Selection.NumberFormat = &quot;hh:mm&quot;
                    Range(&quot;B2&quot;).Select
                 End If
            End If
                                                  
        Next MyCell
       
        End Sub
    
         Function SheetExists(shtName As String, Optional wb As Workbook) As Boolean
        Dim sht As Worksheet
    
         If wb Is Nothing Then Set wb = ThisWorkbook
         On Error Resume Next
         Set sht = wb.Sheets(shtName)
         On Error GoTo 0
         SheetExists = Not sht Is Nothing
         End Function
    
        Public Sub ChooseSheet(ByVal SheetName As String)
        Sheets(SheetName).Select
        End Sub

End result looks like this:

使用Excel VBA添加表格

Here's my sample workbook without any codes: https://drive.google.com/file/d/16logfbrvoK3CVKb-j-g4167pvU_BoWYI/view?usp=sharing

答案1

得分: 1

这个方法应该可以帮助你入门。

> 注意:代码注释中有一些待办事项。

步骤:

  1. 将你的数据库范围转换为一个名为 "TableDatabase" 的Excel结构化表。

请参阅这篇文章

  1. 在名为 "Database" 的工作表后添加以下代码:
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)

    Application.ScreenUpdating = False
    DatabaseManager.Change Target
    Application.ScreenUpdating = True

End Sub
  1. 添加一个模块并将其命名为 "DatabaseManager"

  2. 在 "DatabaseManager" 模块中添加以下代码:

Option Explicit

Private Const DATABASE_TABLE_NAME As String = "TableDatabase"
Private Const DATABASE_MAINCAT_COLUMN_HEADER As String = "Main Category"
Private Const DATABASE_SUBCAT_COLUMN_HEADER As String = "Sub Category"

Private Const TABLE_OFFSET_ROWS As Long = 5
Private Const TABLE_COLUMN_LOCATION As Long = 1 ' 1 = A

Public Sub Change(ByVal Target As Range)

    Dim databaseTable As ListObject
    Dim tableRow As Long

    Set databaseTable = Range(DATABASE_TABLE_NAME).ListObject

    Select Case True
    Case Not Intersect(Target, databaseTable.ListColumns(DATABASE_MAINCAT_COLUMN_HEADER).DataBodyRange) Is Nothing
        ' TODO: 验证是否添加、更新或删除主要类别

        ' Case: 添加主要类别工作表
        AddSheetByTitle Target.Value2, Target.Parent

        ' TODO: 更新、删除情况

    Case Not Intersect(Target, databaseTable.ListColumns(DATABASE_SUBCAT_COLUMN_HEADER).DataBodyRange) Is Nothing
        ' TODO: 验证是否添加、更新或删除子类别
        tableRow = Target.Row - databaseTable.HeaderRowRange.Row + 1

        ' Case: 添加子类别表
        AddTableInSheetByName databaseTable.ListColumns(DATABASE_MAINCAT_COLUMN_HEADER).Range(tableRow), Target.Value2, Target.Parent

        ' TODO: 更新、删除情况

    Case Else

    End Select

End Sub

Public Function AddSheetByTitle(ByVal Title As String, Optional ByVal ReturnSheet As Worksheet) As Worksheet

    ' TODO: 验证工作表名称是否有效

    If SheetExists(Title) = True Then Exit Function

    Dim newWorksheet As Worksheet
    Set newWorksheet = ThisWorkbook.Worksheets.Add(after:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))

    ' 重命名新工作表
    newWorksheet.Name = Title

    ' 返回到以前的工作表
    If Not ReturnSheet Is Nothing Then ReturnSheet.Activate

    Set AddSheetByTitle = newWorksheet

End Function

Public Function AddTableInSheetByName(ByVal TargetSheetName As String, ByVal TableName As String, Optional ByVal ReturnSheet As Worksheet) As ListObject

    Dim targetSheet As Worksheet
    Dim targetTable As ListObject
    Dim lastRow As Long

    If SheetExists(TargetSheetName) = False Then
        Set targetSheet = AddSheetByTitle(TargetSheetName)
    End If

    If TableExists(TableName) = True Then Exit Function

    Set targetSheet = ThisWorkbook.Worksheets(TargetSheetName)

    lastRow = targetSheet.Cells(targetSheet.Rows.Count, 1).End(xlUp).Row

    Set targetTable = targetSheet.ListObjects.Add(SourceType:=xlSrcRange, Source:=targetSheet.Cells(lastRow, TABLE_COLUMN_LOCATION).Offset(TABLE_OFFSET_ROWS))

    targetTable.Name = TableName

    ' 设置表头和内容
    targetTable.HeaderRowRange.Cells(1).Value2 = TableName

    ' 返回到以前的工作表
    If Not ReturnSheet Is Nothing Then ReturnSheet.Activate

End Function

Private Function SheetExists(ByVal SheetName As String) As Boolean
    Dim evalSheet As Worksheet

    On Error Resume Next
    Set evalSheet = ThisWorkbook.Sheets(SheetName)
    On Error GoTo 0

    SheetExists = (Not evalSheet Is Nothing)
End Function

Private Function TableExists(ByVal TableName As String) As Boolean
    Dim evalTable As ListObject
    Dim evalName As String
    ' TODO: 检查 TableName 是否有效(搜索无效字符)
    evalName = Replace(TableName, " ", "_")
    On Error Resume Next
    TableExists = (Range(evalName).ListObject.Name = TableName)
    On Error GoTo 0
End Function

> 注意:你的最终结果属于特定类型的表格。我的代码
> (正如你最初要求的)将一个新表格添加到工作表中。另一种方法是复制(复制)源表格并重命名它。

希望这有所帮助。如果有帮助,请记得标记答案。

英文:

This approach should get you started.

> Note: There are several TODOs in the code's comments.

Steps:

  1. Convert your database range to an Excel structured table called (TableDatabase).

See this article

  1. Add this code behind the sheet "Database"

    Option Explicit

    Private Sub Worksheet_Change(ByVal Target As Range)

     Application.ScreenUpdating = False
     DatabaseManager.Change Target
     Application.ScreenUpdating = True
    

    End Sub

使用Excel VBA添加表格

  1. Add a module and call it "DatabaseManager"

使用Excel VBA添加表格

  1. Add this code to the DatabaseManager module:

    Option Explicit

    Private Const DATABASE_TABLE_NAME As String = "TableDatabase"
    Private Const DATABASE_MAINCAT_COLUMN_HEADER As String = "Main Category"
    Private Const DATABASE_SUBCAT_COLUMN_HEADER As String = "Sub Category"

    Private Const TABLE_OFFSET_ROWS As Long = 5
    Private Const TABLE_COLUMN_LOCATION As Long = 1 ' 1 = A

    Public Sub Change(ByVal Target As Range)

     Dim databaseTable As ListObject
     Dim tableRow As Long
    
     Set databaseTable = Range(DATABASE_TABLE_NAME).ListObject
    
     Select Case True
     Case Not Intersect(Target, databaseTable.ListColumns(DATABASE_MAINCAT_COLUMN_HEADER).DataBodyRange) Is Nothing
         &#39; TODO: Validate if adding, updating or deleting a main category
    
         &#39; Case: Add a main category sheet
         AddSheetByTitle Target.Value2, Target.Parent
    
         &#39; TODO: Case updating, deleting
    
     Case Not Intersect(Target, databaseTable.ListColumns(DATABASE_SUBCAT_COLUMN_HEADER).DataBodyRange) Is Nothing
         &#39; TODO: Validate if adding, updating  or deleting a sub category
         tableRow = Target.Row - databaseTable.HeaderRowRange.Row + 1
    
         &#39; Case: Add a subcategory table
         AddTableInSheetByName databaseTable.ListColumns(DATABASE_MAINCAT_COLUMN_HEADER).Range(tableRow), Target.Value2, Target.Parent
    
         &#39; TODO: Case updating, deleting
    
     Case Else
    
     End Select
    

    End Sub

    Public Function AddSheetByTitle(ByVal Title As String, Optional ByVal ReturnSheet As Worksheet) As Worksheet

     &#39; TODO: Validate if sheet name is valid
    
     If SheetExists(Title) = True Then Exit Function
    
     Dim newWorksheet As Worksheet
     Set newWorksheet = ThisWorkbook.Worksheets.Add(after:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
    
     &#39; Rename the new sheet
     newWorksheet.Name = Title
    
     &#39; Return to a previous sheet
     If Not ReturnSheet Is Nothing Then ReturnSheet.Activate
    
     Set AddSheetByTitle = newWorksheet
    

    End Function

    Public Function AddTableInSheetByName(ByVal TargetSheetName As String, ByVal TableName As String, Optional ByVal ReturnSheet As Worksheet) As ListObject

     Dim targetSheet As Worksheet
     Dim targetTable As ListObject
     Dim lastRow As Long
    
     If SheetExists(TargetSheetName) = False Then
         Set targetSheet = AddSheetByTitle(TargetSheetName)
     End If
    
     If TableExists(TableName) = True Then Exit Function
    
     Set targetSheet = ThisWorkbook.Worksheets(TargetSheetName)
    
     lastRow = targetSheet.Cells(targetSheet.Rows.Count, 1).End(xlUp).Row
    
     Set targetTable = targetSheet.ListObjects.Add(SourceType:=xlSrcRange, Source:=targetSheet.Cells(lastRow, TABLE_COLUMN_LOCATION).Offset(TABLE_OFFSET_ROWS))
    
     targetTable.Name = TableName
    
     &#39; Set table headers and content
     targetTable.HeaderRowRange.Cells(1).Value2 = TableName
    
     &#39; Return to a previous sheet
     If Not ReturnSheet Is Nothing Then ReturnSheet.Activate
    

    End Function

    Private Function SheetExists(ByVal SheetName As String) As Boolean
    Dim evalSheet As Worksheet

     On Error Resume Next
     Set evalSheet = ThisWorkbook.Sheets(SheetName)
     On Error GoTo 0
    
     SheetExists = (Not evalSheet Is Nothing)
    

    End Function

    Private Function TableExists(ByVal TableName As String) As Boolean
    Dim evalTable As ListObject
    Dim evalName As String
    ' TODO: check if TableName is valid (search for invalid chars)
    evalName = Replace(TableName, " ", "_")
    On Error Resume Next
    TableExists = (Range(evalName).ListObject.Name = TableName)
    On Error GoTo 0
    End Function

> Note: Your end result belongs to an specific type of table. My code
> adds (as you initially asked) a new table to the sheet. The alternative would be to copy (duplicate) a source table and rename it.

Hope this helps. Remember to mark the answer if it does.

huangapple
  • 本文由 发表于 2020年1月3日 22:21:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/59580187.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定