[英]Export SQL Query to Excel File with multiple sheets
I have the below query (thanks to stackoverflow) that will loop through a list of groups and give me the permissions the group will have for a category. 我有以下查询(由于stackoverflow),它将遍历组列表,并为我提供该组对某个类别的权限。 In Linqpad I can export the result into one Excel sheet, but I was wondering if it was possible to export each group result in the loop to a separate sheet in the Excel file.
在Linqpad中,我可以将结果导出到一个Excel工作表中,但是我想知道是否可以将循环中的每个组结果导出到Excel文件中的单独工作表中。 I was going to try in C# first, but I was wondering if it can be done via SQL or Linqpad as well.
我打算先在C#中尝试,但是我想知道是否可以通过SQL或Linqpad来完成。
Also, Ad Hoc Distributed Queries are disabled on the server. 此外,服务器上的临时分布式查询也被禁用。
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
I just decided to use an Excel macro after I exported the query from Linqpad. 从Linqpad导出查询后,我决定使用Excel宏。 My VBA is a little rusty and I have a couple of small issues that I need to work out (I'm sure there is an easier way than I did it), but this is okay for now.
我的VBA有点生锈,我有几个小问题需要解决(我敢肯定有比我更容易的方法),但是现在还可以。 Basically, I searched for every row in column one with GroupName as the value.
基本上,我以GroupName作为值搜索第一列中的每一行。 From there I stored those in an array and used the different in between each for each sheet to be added.
从那里,我将它们存储在一个数组中,并在每个要添加的工作表之间使用不同的内容。
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.