简体   繁体   English

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

[英]How to unlock and lock Excel cells for running a macro

I have a spreadsheet that has two buttons - To retrieve records from database and another one to upload changes from excel to database.我有一个电子表格,它有两个按钮 - 从数据库中检索记录,另一个用于将更改从 excel 上传到数据库。 The macro for retrieving records from Database is as follows.从数据库中检索记录的宏如下。 Now after retrieving the records, I want the users only to edit certain columns( here the columns from January to Scenario) so that the users, after updating those cells can click on the update button to save the changes to the database.现在在检索记录后,我希望用户只编辑某些列(这里是从一月到场景的列),以便用户在更新这些单元格后可以单击更新按钮将更改保存到数据库中。 However, I don't want them to touch the other columns ( EmpID through Status).I want a macro that would lock those columns after data retrieval and unlock while retrieving the records on clicking the Retrieval button.但是,我不希望它们接触其他列(从 EmpID 到状态)。我想要一个宏,可以在数据检索后锁定这些列,并在单击检索按钮时检索记录时解锁。 This is because I am clearing the worksheet whenever I click on the retrieve records buttons.这是因为每当我单击检索记录按钮时,我都会清除工作表。 I tried several methods and it's not working.我尝试了几种方法,但都不起作用。 I would appreciate your help.我会很感激你的帮助。

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

Thanks, Hema谢谢,赫马

One of the best ways to learn how to do something in VBA is simply to perform the task with the Macro Recorder on.学习如何在 VBA 中做某事的最好方法之一就是在打开宏记录器的情况下执行任务。 That way you will know the basic code required to complete the task.这样你就会知道完成任务所需的基本代码。

It also helps to understand that all cells start off with a property of "Locked" but that only becomes useful when the workbook is Protected using the Review > Protect Sheet option.它还有助于了解所有细胞开始以“锁定”的属性,但是,当保护工作簿使用评论>保护工作表选项仅变得有用。

So to make sure no one can change all any of the cells in your book after the data has been changed, you'd need to protect the workbook using:因此,为了确保在数据更改后没有人可以更改您工作簿中的所有单元格,您需要使用以下方法保护工作簿:

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

The various options could be changed or removed depending on what you want done.可以根据您想要完成的操作更改或删除各种选项。

As I understand it, you want only certain columns locked.据我了解,您只希望锁定某些列。 In this case, you actually have to unlock the cells you will allow them to enter - so you have to think about it backwards.在这种情况下,您实际上必须解锁您将允许它们进入的单元格 - 因此您必须向后考虑。

This line of code would set the Locked property of the cells C1:C1000 to False so that when the Workbook is Protected, the user can still edit the cells:这行代码会将单元格 C1:C1000 的Locked属性设置为False,这样当工作簿受保护时,用户仍然可以编辑单元格:

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

If you have any other questions, just post.如果您有任何其他问题,只需发布​​。

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

After your:在您之后:

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

Place this code:放置此代码:

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

When you enter the procedure where you need to rewrite everything:当您进入需要重写所有内容的程序时:

Public Sub RetrieveDBToWorkSheet()

Place this code to unlock the whole sheet:放置此代码以解锁整个工作表:

ActiveSheet.Unprotect  ' This will unprotect the whole sheet

You have to remember to unlock all the columns on the sheet first.您必须记住首先解锁工作表上的所有列。 If you don't, then the protect will lock down all of your columns (even though you specifically "locked" the range you want).如果您不这样做,那么保护将锁定您的所有列(即使您专门“锁定”了您想要的范围)。 This is unintuitive and has baffled many excel users.这是不直观的,并让许多 excel 用户感到困惑。

Have you already tried activesheet.protect?您是否已经尝试过 activesheet.protect?

At the beginning of the script you would have to add the following to "unprotect" the sheet to work with.在脚本的开头,您必须添加以下内容以“取消保护”要使用的工作表。

    activesheet.unprotect

Then the script is run.然后运行脚本。 At the end of your sub first define the columns which you want your user to be able to change: (As an example Colum B)在您的子文件末尾,首先定义您希望用户能够更改的列:(例如 B 列)

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

following that, protect the sheet然后,保护工作表

    activesheet.protect

I think it should work.我认为它应该工作。

I manage to unprotect a Microsoft Excel 97-2003 Worksheet (.xls) following the next steps我设法按照以下步骤取消保护 Microsoft Excel 97-2003 工作表 (.xls)

  1. Open the file打开文件
  2. Allow editing and macros允许编辑和宏
  3. Click ALT + F11单击 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.单击 ALT + F11 返回到工作表。

  6. Click ALT + F8 to go to Macro.单击 ALT + F8 转到宏。
  7. Run the UnprotectSheet created previously.运行之前创建的 UnprotectSheet。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM