如何在运行宏时解锁和锁定Excel单元格

3
我有一个电子表格,其中有两个按钮 - 一个用于从数据库检索记录,另一个用于将更改从Excel上传到数据库。从数据库检索记录的宏如下所示。现在,在检索记录后,我希望用户仅编辑某些列(这里是从1月到情景的列),以便用户在更新这些单元格后可以单击更新按钮将更改保存到数据库中。但是,我不希望他们触及其他列(EmpID到Status)。我想要一个宏,可以在数据检索后锁定这些列,并在单击检索按钮时解锁这些列。这是因为每当我点击检索记录按钮时,我都会清除工作表。我尝试了几种方法,但没有成功。我将感激您的帮助。
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。

如果问题已经解决,请将最合适的答案标记为带有左侧勾号的答案。 - ti7
4个回答

2

学习如何在VBA中完成某项任务最好的方法之一就是使用宏录制器进行操作。这样,您将了解完成任务所需的基本代码。

此外,了解所有单元格都具有“锁定”属性也很有帮助,但只有在使用“审阅>保护工作表”选项保护工作簿时才有用。

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

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

2

在您完成以下操作之后:

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

在保护表格之前,您必须记得先解锁所有列。如果不这样做,那么保护将锁定所有列(即使您特别“锁定”了想要的范围)。这是不直观的,让许多Excel用户感到困惑。


1

我成功地解除了一个Microsoft Excel 97-2003工作表(.xls)的保护,按照以下步骤进行:

  1. Open the file
  2. Allow editing and macros
  3. Click ALT + F11
  4. Place the following code

    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. Click ALT + F11 to go back to the sheet.

  6. Click ALT + F8 to go to Macro.
  7. Run the UnprotectSheet created previously.

1

您是否已经尝试过 activesheet.protect?

在脚本开头,您需要添加以下内容来“取消保护”工作表。

    activesheet.unprotect

然后运行脚本。在你的子程序结束时,首先定义你希望用户能够更改的列:(例如B列)

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

以下是保护工作表的步骤。
    activesheet.protect

我认为它应该可以工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接