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
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
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.
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.
I manage to unprotect a Microsoft Excel 97-2003 Worksheet (.xls) following the next steps
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
Click ALT + F11 to go back to the sheet.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.