How to unlock and lock Excel cells for running a macro

左心房为你撑大大i 提交于 2020-01-13 18:18:27

问题


I have a spreadsheet that has two buttons - To retrieve records from database and another one to upload changes from excel to database. 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. 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


回答1:


One of the best ways to learn how to do something in VBA is simply to perform the task with the Macro Recorder on. 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:

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




回答2:


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.




回答3:


Have you already tried 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)

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

following that, protect the sheet

    activesheet.protect

I think it should work.




回答4:


I manage to unprotect a Microsoft Excel 97-2003 Worksheet (.xls) following the next steps

  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.


来源:https://stackoverflow.com/questions/44833422/how-to-unlock-and-lock-excel-cells-for-running-a-macro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!