Excel 带有链接到按钮的宏的工作簿保护正在阻止power query完成其加载

Excel 带有链接到按钮的宏的工作簿保护正在阻止power query完成其加载,excel,vba,security,powerquery,Excel,Vba,Security,Powerquery,我有一个Excel文件,带有连接到SQL server的电源查询。此文件分发给组织中的各个经理,每个经理都有自己独特的角色,因此每个excel都是为其用户量身定制的。为了防止查询被误用,我使用了工作簿保护,这样用户就不能修改查询和下载不在其职权范围内的数据。但是,为了允许用户从SQL下载工作表更新,有一个按钮,用户可以单击该按钮,Power Query将刷新表。该按钮链接到VBA代码(请注意,我还保护VBA代码不被查看): 我遇到的问题是,Power Query在刷新工作表中的结束表之前等待该宏

我有一个Excel文件,带有连接到SQL server的电源查询。此文件分发给组织中的各个经理,每个经理都有自己独特的角色,因此每个excel都是为其用户量身定制的。为了防止查询被误用,我使用了工作簿保护,这样用户就不能修改查询和下载不在其职权范围内的数据。但是,为了允许用户从SQL下载工作表更新,有一个按钮,用户可以单击该按钮,Power Query将刷新表。该按钮链接到VBA代码(请注意,我还保护VBA代码不被查看):

我遇到的问题是,Power Query在刷新工作表中的结束表之前等待该宏完成,因此,即使它可以连接到SQL并获取数据,由于某种原因,它也会无限期挂起,直到宏完成,然后才尝试刷新工作表的表(在B6)。这会导致查询上出现“下载未完成”错误消息,因为在宏末尾启用工作簿保护会阻止进一步更新。如果我去掉代码的最后一部分,即它不会重新保护工作簿,则Power Query会正确完成表刷新


你知道如何在保护开始之前完成表格刷新吗?

我设法找到了解决方案!基本上,我要做的是将保护重新应用作为一个单独的事件。我在上面加了双重密码保护;一个用于运行代码,另一个用于一般保护,然后我在保护部分保留了打开的VBA命令。然后,我做了另一个命令,该命令跟随对工作表的更改,另外两个命令在工作簿打开和关闭时运行。对于用户来说,这些都好像工作簿一直被锁定一样

表中的代码如下所示:

Private Sub Update_Click()

Dim passwordDos As Variant
          passwordDos = Application.InputBox("Enter Password", "Password Protected")

Select Case passwordDos
Case Is = False
                  'do nothing
Case Is = "PASSWORD"    'this unlocks the sheet update
    ThisWorkbook.Unprotect password:="protection"
    Dim con As WorkbookConnection
    Dim Cname As String

    For Each con In ActiveWorkbook.Connections
        If Left(con.Name, 8) = "Query - " Then
            Cname = con.Name
                With ActiveWorkbook.Connections(Cname).OLEDBConnection
                    .BackgroundQuery = False
                    .Refresh
                End With
        End If
    Next
    Application.CalculateUntilAsyncQueriesDone
    Do While Application.CalculationState <> xlDone
        DoEvents
        Loop
    MsgBox "Update complete!"
Case Else
    MsgBox "Incorrect Password"
End Select

End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not ThisWorkbook.ProtectStructure Then ThisWorkbook.Protect password:="protection"
End Sub
请注意,在受保护的工作簿上仅使用“ThisWorkbook.Protect”似乎有一个奇怪的副作用,即它将取消对工作簿的保护而不是保护。毫无意义,所以那一定是个bug

基本上,当文件第一次打开时,Workbook_Open()命令强制保护工作簿结构。类似地,BeforeClose将强制工作簿在关闭前受到保护。工作表选择更改监视包含结束表的工作表,因此当该表更新时,同样的保护也会生效。这总是在查询完成后发生。让程序向最终用户请求另一个密码背后的想法是,单击按钮,用户执行意外操作可能会使工作表处于未受保护的状态,因此我希望确保它在继续更新时在VBA基础上生成一个阈值,否则会将其锁定。实际上,我可能会添加另一行,在解锁工作簿之前首先检查与服务器的连接,以防SQL连接出错。然而,这里的想法是,只有经理知道更新密码,因此一旦他们关闭工作簿并将其传递给不允许查看特定工作簿中内容以外的其他内容的人,其他人将无法运行任何更新或查看任何代码。这也是VBA视图保护方便的地方

Private Sub Update_Click()

Dim passwordDos As Variant
          passwordDos = Application.InputBox("Enter Password", "Password Protected")

Select Case passwordDos
Case Is = False
                  'do nothing
Case Is = "PASSWORD"    'this unlocks the sheet update
    ThisWorkbook.Unprotect password:="protection"
    Dim con As WorkbookConnection
    Dim Cname As String

    For Each con In ActiveWorkbook.Connections
        If Left(con.Name, 8) = "Query - " Then
            Cname = con.Name
                With ActiveWorkbook.Connections(Cname).OLEDBConnection
                    .BackgroundQuery = False
                    .Refresh
                End With
        End If
    Next
    Application.CalculateUntilAsyncQueriesDone
    Do While Application.CalculationState <> xlDone
        DoEvents
        Loop
    MsgBox "Update complete!"
Case Else
    MsgBox "Incorrect Password"
End Select

End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not ThisWorkbook.ProtectStructure Then ThisWorkbook.Protect password:="protection"
End Sub
Private Sub Workbook_Open()
If Not ThisWorkbook.ProtectStructure Then ThisWorkbook.Protect password:="$uominenICT"
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
If Not ThisWorkbook.ProtectStructure Then ThisWorkbook.Protect password:="$uominenICT"
ThisWorkbook.Save
End Sub