如何解锁和锁定Excel单元以运行宏

时间:2017-06-29 19:24:30

标签: excel vba excel-vba

我有一个包含两个按钮的电子表格 - 从数据库中检索记录,另一个用于将更改从Excel上传到数据库。用于从数据库检索记录的宏如下。现在,在检索记录之后,我希望用户只编辑某些列(此处是从1月到Scenario的列),以便用户在更新这些单元格后可以单击更新按钮将更改保存到数据库。但是,我不希望它们触及其他列(通过状态的EmpID)。我想要一个在数据检索后锁定这些列的宏,并在单击“检索”按钮时检索记录时解锁。这是因为每当我点击检索记录按钮时,我都会清除工作表。我尝试了几种方法但它不起作用。我很感激你的帮助。

Public Sub RetrieveDBToWorkSheet()
Dim sQry As String
Dim iRows As Integer
Dim iCols As Integer
Dim SQL As String



On Error GoTo ErrHandler



'Clear worksheet
Call ClearExistingRows(4)

'Create ADODB Recordset for retrieved data
Call DBConnection.OpenDBConnection

'Create Recordset
Dim rsMY_Resources As ADODB.Recordset
Set rsMY_Resources = New ADODB.Recordset

SQL = "SELECT  EmpID, EName, CCNum, CCName, ProgramNum, ProgramName, ResTypeNum, ResName, Status, January, February, March, April, May, June, July, August, September, October, November, December, Total_Year, Year, Scenario from Actual_FTE2"

'Query the database

rsMY_Resources.Open SQL, DBConnection.oConn, adOpenStatic, adLockReadOnly
If rsMY_Resources.EOF = True Then
    MsgBox ("No record found in database")
    Exit Sub
End If

'Fill excel active sheet, starting from row# 3
iRows = 3
For iCols = 0 To rsMY_Resources.Fields.Count - 1
    ActiveSheet.Cells(iRows, iCols + 1).Value = rsMY_Resources.Fields(iCols).Name
Next
ActiveSheet.Range(ActiveSheet.Cells(iRows, 1), ActiveSheet.Cells(iRows, rsMY_Resources.Fields.Count)).Font.Bold = True

iRows = iRows + 1
ActiveSheet.Range("A" + CStr(iRows)).CopyFromRecordset rsMY_Resources

iRows = rsMY_Resources.RecordCount

'Clean up
rsMY_Resources.Close:
Set rsMY_Resources = Nothing

Call DBConnection.CloseDBConnection


MsgBox (CStr(iRows) + " records have been retrieved from the database!")


Exit Sub

ErrHandler:
MsgBox (Error)

End Sub

Public Sub ClearExistingRows(lRowStart As Long)
Dim lLastRow As Long
Dim iLastCol As Integer

 If (Not (Cells.Find("*", Range("A1"), xlFormulas, , xlByRows, xlPrevious) 
 Is Nothing)) Then
    lLastRow = Cells.Find("*", Range("A1"), xlFormulas, , 
   xlByRows,xlPrevious).Row ' Find the last row with data

    If (lLastRow >= lRowStart) Then
        iLastCol = Cells.Find("*", Range("A1"), xlFormulas, , xlByColumns, 
    xlPrevious).Column ' Find the last column with data
        Range(Cells(lRowStart, 1), Cells(lLastRow, iLastCol)).Select
        Selection.EntireRow.Delete
       End If
    End If
   End Sub

谢谢, HEMA

4 个答案:

答案 0 :(得分:1)

学习如何在VBA中执行某些操作的最佳方法之一就是使用宏记录器执行任务。这样你就会知道完成任务所需的基本代码。

它还有助于理解所有单元格都以“已锁定”属性开始,但仅当工作簿受保护时才使用 Review>保护表选项。

因此,为了确保在数据更改后没有人可以更改您图书中的所有单元格,您需要使用以下方法保护工作簿:

ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True

根据您的需要,可以更改或删除各种选项。

据我了解,您只想锁定某些列。在这种情况下,你实际上必须解锁你允许他们进入的单元格 - 所以你必须向后思考它。

这行代码会将单元格C1:C1000的锁定属性设置为 False ,这样当工作簿受到保护时,用户仍然可以编辑单元格:

Range("C1:C1000").Locked = False

如果您有任何其他问题,请发布。

请参阅此处的Microsoft文档: https://msdn.microsoft.com/en-us/VBA/excel-vba/articles/range-locked-property-excel

答案 1 :(得分:1)

您是否已尝试过activesheet.protect?

在脚本开头,您必须添加以下内容以“取消保护”要使用的工作表。

    activesheet.unprotect

然后运行脚本。在您的sub结束时,首先定义您希望用户能够更改的列:(作为Colum B的示例)

    Columns("B:B").Select 
    Selection.Locked = False

然后,保护工作表

    activesheet.protect

我认为它应该有用。

答案 2 :(得分:1)

在你之后:

MsgBox (CStr(iRows) + " records have been retrieved from the database!")

放置此代码:

Dim rngCol As Range ' Create a Range object

Set rngCol = ActiveSheet.Range("A:Z") ' Select all columns on sheet
   rngCol.Locked = False              ' Unlock all columns
Set rngCol = ActiveSheet.Range("A:I") ' Now Select columns EmpID - Status
   rngCol.Locked = True               ' Lock only those columns
   ActiveSheet.Protect                ' Protect will now only protect the Locked columns

当您输入需要重写所有内容的程序时:

Public Sub RetrieveDBToWorkSheet()

放置此代码以解锁整张表格:

ActiveSheet.Unprotect  ' This will unprotect the whole sheet

您必须记住首先解锁工作表上的所有列。如果你没有,那么保护将锁定你的所有列(即使你特意"锁定"你想要的范围)。这是不直观的,并且困扰了许多优秀的用户。

答案 3 :(得分:0)

按照以下步骤,我设法取消保护Microsoft Excel 97-2003工作表(.xls)

  1. 打开文件
  2. 允许编辑和宏
  3. 点击ALT + F11
  4. 放置以下代码

    Sub UnprotectSheet()
    
    Dim i, i1, i2, i3, i4, i5, i6 As Integer, j As Integer, k As Integer, l As Integer, m As Integer, n As Integer
    On Error Resume Next
    For i = 65 To 66
    For j = 65 To 66
    For k = 65 To 66
    For l = 65 To 66
    For m = 65 To 66
    For i1 = 65 To 66
    For i2 = 65 To 66
    For i3 = 65 To 66
    For i4 = 65 To 66
    For i5 = 65 To 66
    For i6 = 65 To 66
    For n = 32 To 126
    ActiveSheet.Unprotect Chr(i) & Chr(j) & Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
    If ActiveSheet.ProtectContents = False Then
    MsgBox "One usable password is " & Chr(i) & Chr(j) & _
    Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & _
    Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
    Exit Sub
    End If
    Next
    Next
    Next
    Next
    Next
    Next
    Next
    Next
    Next
    Next
    Next
    Next
    End Sub
    
  5. 单击ALT + F11返回工作表。

  6. 单击ALT + F8转到宏。
  7. 运行先前创建的UnprotectSheet。