簡體   English   中英

將SQL查詢導出到具有多個工作表的Excel文件

[英]Export SQL Query to Excel File with multiple sheets

我有以下查詢(由於stackoverflow),它將遍歷組列表,並為我提供該組對某個類別的權限。 在Linqpad中,我可以將結果導出到一個Excel工作表中,但是我想知道是否可以將循環中的每個組結果導出到Excel文件中的單獨工作表中。 我打算先在C#中嘗試,但是我想知道是否可以通過SQL或Linqpad來完成。

此外,服務器上的臨時分布式查詢也被禁用。

SELECT GroupId, Name
INTO #GroupTemp
FROM [Group]

DECLARE @Id INT

WHILE EXISTS (
    SELECT * FROM #GroupTemp
    )
BEGIN
    SELECT TOP 1 @Id = GroupId
    FROM #Temp

    SELECT g.NAME AS 'GroupName'
        ,c.NAME AS 'CategoryName'
        ,c.CategoryId
        ,c.ParentCategoryId
        ,p.[Read]
        ,p.Edit
        ,p.[Delete]
        ,p.[Add]
        ,p.Share
        ,p.Admin
    FROM GroupCategoryPermission p
    INNER JOIN [Group] g ON p.GroupId = @Id
    INNER JOIN Category c ON p.CategoryID = c.CategoryID
    WHERE g.GroupId = @Id

    DELETE #GroupTemp
    WHERE GroupId = @Id
END

從Linqpad導出查詢后,我決定使用Excel宏。 我的VBA有點生銹,我有幾個小問題需要解決(我敢肯定有比我更容易的方法),但是現在還可以。 基本上,我以GroupName作為值搜索第一列中的每一行。 從那里,我將它們存儲在一個數組中,並在每個要添加的工作表之間使用不同的內容。

Option Explicit

Private Function Sleep()
    Application.Wait Now + 1 / (24 * 60 * 60.0# * 2)
End Function

'Remove 1st row of Sheet 1 and blank rows from sheet
Private Function CheckEmpty()
    On Error Resume Next
    Worksheets(1).Select()
    Columns("A").SpecialCells(xlBlanks).EntireRow.Delete()
    Rows("1:1").Select()
    Selection.Delete Shift:=xlUp
End Function

'Function to get the name of the group and name the sheet that name
Private Function NameSheet()
    Dim groupName As String
    groupName = ActiveSheet.Range("A2").Value
    If Len(groupName) > 31 Then
        groupName = Left(groupName, 31)
        ActiveSheet.Name = groupName
    Else
        ActiveSheet.Name = groupName
    End If
End Function

'This will format the sheet
Private Function FormatSheet()
    Cells.Select()
    With Selection
        .WrapText = False
    End With
    Rows("1:1").Select()
    Selection.Font.Bold = True
    Cells.Select()
    With Selection
        .HorizontalAlignment = xlLeft
        .VerticalAlignment = xlBottom
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = False
        .Columns.AutoFit()
    End With
End Function

'Main sub to separate groups into their own sheets
Sub SplitToSheets()
    'Variables
    Dim ws As Worksheet, rng As Range, cell As Range, findString As String
    Dim counter As Long, numbers() As Long, lastRow As Long, firstRow As Long
    'Clean sheet 1
    Worksheets(1).Activate()
    CheckEmpty()
    FormatSheet()
    'Set the range that we will be checking
    firstRow = Rows("1:1").Row
    lastRow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row
    rng = Range("A" & firstRow & ":" & "A" & lastRow)
    rng.Select()

    'Set the counter so we loop through array
    counter = 1
    'Loop through array and store row numbers
    For Each cell In rng
        If cell.Value = "GroupName" Then
            ReDim Preserve numbers(counter)
            numbers(counter) = cell.Row
            'Increase counter by 1
            counter = counter + 1
        End If
    Next

    'Separate groups to sheet using numbers array
    'Variables
    Dim inx As Long, rStart As Long, rEnd As Long, ind As Long
    'Copy first group to new sheet on it's own (need to change logic to avoid separation, eventually)
    rStart = numbers(1)
    rEnd = numbers(2) - 1
    Rows(rStart & ":" & rEnd).Select()
    Selection.Copy()
    Sheets.Add After:=Sheets(Sheets.Count)
    Selection.PasteSpecial(Paste:=xlPasteValuesAndNumberFormats, Operation:= _
    xlNone, SkipBlanks:=False, Transpose:=False)
    NameSheet()
    FormatSheet()
    'Index Counter for looping through array
    ind = 0
    For inx = LBound(numbers) To UBound(numbers)
        'Need to loop once and make sure the counter is greater than 1
        If ind > 0 Then
            'Revert to sheet 1
            Worksheets(1).Select()
            'Start row number
            rStart = numbers(ind)
            'End row number
            rEnd = (numbers(ind) - numbers(ind - 1))
            'Selection must start on second group
            If rEnd > 1 Then
                'Select range
                Rows(rStart & ":" & rStart + rEnd).Select()
                'Copy
                Selection.Copy()
                'Add next availble sheet
                Sheets.Add After:=Sheets(Sheets.Count)
                'Paste values
                Selection.PasteSpecial(Paste:=xlPasteValuesAndNumberFormats, Operation:= _
                xlNone, SkipBlanks:=False, Transpose:=False)
                'Set sheet name and rename to match group
                NameSheet()
                FormatSheet()
                Sleep()
            End If
        End If
        'Increase index by 1
        ind = ind + 1
    Next
    'This deletes the main sheet that we no longer need
    Application.DisplayAlerts = False
    Worksheets(1).Delete()
    Application.DisplayAlerts = True
    Worksheets(1).Activate()
End Sub

'This macro will give option to seach for sheet
Sub GetSheet()
    Dim SearchData As String
    SearchData = InputBox("Enter 'exact' group name.")
    If SearchData <> vbNullString Then
        On Error Resume Next
        Sheets(SearchData).Activate()
        If Err.Number <> 0 Then MsgBox "Unable to find group named: " & SearchData
        On Error GoTo 0
    End If
End Sub

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM