我有一个包含两个按钮的电子表格 - 从数据库中检索记录,另一个用于将更改从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
答案 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)
放置以下代码
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
单击ALT + F11返回工作表。