VBA Excel-How to restrict users not to paste on specific rows? - vba

I have an Excel like shown below which is a sharedExcel.
Now i should not allow paste option for the rows which have backcolour as GRAY(These are not fixed at runtime any row may get GRAY colour). As it sharedExcel and i can't use the Lock property. Any help wouls be appreciated greatly.

Using a color as a property that is used to check true / false is bad behaviour.
You can get around this by for example adding a column (hidden if needed) with 0 / 1 or TRUE / FALSE which you make accessible by for example a combobox (then you can still adapt the color into gray by clicking this cbb box).
The you can check on a dynamically composed range via a Sheet event on_Change.
The basic syntax for the sheet event:
Private Sub Worksheet_Change(ByVal Target As Range)
'Set range dynamically instead of this hard coded example
If Not Intersect(Target, Thisworkbook.Sheets(1).Range("A1:A10")) Is Nothing Then
'Do something
End If
End Sub

After spending some time on this problem i have coded following lines. It work's fine. Here i have taken another spreadsheet called PasteSheet for coding purpose but i am not showing it to user at any moment.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Application.CutCopyMode Then
SelectedRow = ActiveCell.Row
With Sheets("PasteSheet")
.Activate
.Range("A1").PasteSpecial xlPasteValues
CR = Selection.Rows.Count
End With
Worksheets("ActualSheet").Activate
For k = SelectedRow To (SelectedRow + CR)
If Worksheets("ActualSheet").Cells(k, 30).Interior.Color = RGB(215, 215, 215) Then
Application.EnableEvents = False
MsgBox "Pasting is not allowed here!"
'Clearing data in PasteSheet
Worksheets("PasteSheet").Cells.ClearContents
Worksheets("ActualSheet").Activate
Application.EnableEvents = True
Exit Sub
End If
Next
End If
End Sub

Related

Disable all paste functions for the following vba code

I'm running a target intersect method in excel to prevent a user from pasting over validation cells, problem is, I didn't account for all the paste methods, and pastespecial overrides the cell validations.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("I14:J1000")) Is Nothing Then
On Error Resume Next ' In case there's been no previous action
' Check if the last action was a paste
If Left(Application.CommandBars("Standard").Controls("&Undo").List(1), 5) = "Paste" Then
Application.EnableEvents = False
Application.Undo
Application.EnableEvents = True
End If
End If
End Sub
I used the code below and binded it to Ctrl V, so that it matches the destination formatting, but it overrides the cell validation from the previous code:
Sub PasteWithDestinationFormatting()
ActiveCell.PasteSpecial (xlPasteValues)
End Sub
I'm assuming I need to change ="Paste" to a "PasteSpecial" but it didn't accomplish what I wanted it to do, most likely cause I didn't have the correct location of the PasteSpecial object.
Thanks for the help!

excel hide rows with error values based on dropdown change

I would like to hide rows in column B9-B40 when Index/Match formula returns "N/A" , now I managed to get it done in VBA when the table is static but I have a dynamic table based on drop-down selection which means the number of N/As returned can be different for each time drop-down selection changes.
Here is what I have right now which hides the rows with N/A based on current drop-down selection, my dropdowns are in C2,C3 and C4. But it doesn't takes any further change in the dropdown into consideration afterwards. I am not very competent with the VBA so any help would be great.
Thanks.
Option Explicit
Sub hide_if_error()
Dim MyCell As Range, Rng As Range
Set Rng = Range("B9:B40")
For Each MyCell In Rng
If IsError(MyCell) Then
MyCell.EntireRow.Hidden = True
End If
Next MyCell
End Sub
You can do
Range("B9:B40").SpecialCells(xlCellTypeFormulas, xlErrors).EntireRow.Hidden = True
You will need a test in advance that errors are present though.
That might look like:
Option Explicit
Public Sub hide_if_error()
With ThisWorkbook.Worksheets("Sheet4")
.Range("B9:B40").EntireRow.Hidden = False
If Evaluate("=SUM(IF(ISERROR(" & .Range("B9:B40").Address & "),1))") > 0 Then '<==check if any errors present
.Range("B9:B40").SpecialCells(xlCellTypeFormulas, xlErrors).EntireRow.Hidden = True
End If
End With
End Sub
If necessary, you could link the above to a worksheet change or dropdown change event so it is fired each time there is an update using the dropdown(s)
For example:
If you data validation was in C2:C4 you would put in the code pane for the sheet the following event code:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo ErrHand
If Not Intersect(Target, Range("C2:C4")) Is Nothing Then
Application.EnableEvents = False
hide_if_error
End If
ErrHand:
Application.EnableEvents = True
End Sub
Note:
The worksheet event code goes in the code pane associate with sheet 4:
The other code goes in a standard module (module 1 here):
Example run:

Run a macro automatically every minutes

Good morning
Basically I am importing index data from the web (abcbourse.com) and I make it refresh every minutes.
I created a macro in order to recorder historical values of each index (starting with the CAC40 as you can see in the screenshot, with new values going on column E every minute (each time the data is automatically refreshed)
Here is my macro, working well (see Column E of the screenshot):
Sub Historical_Index()
Dim LastLRow As Integer, CurrentIndexValue As Single
LastRow = Range("E" & Rows.Count).End(xlUp).Row
CurrentIndexValue = Range("B1")
Do
If Not IsEmpty(CurrentIndexValue) = True Then
Cells(LastRow + 1, 5).Value = CurrentIndexValue
Exit Do
End If
Loop
End Sub
My problem is, I want this macro to run every time the data is refreshed. I initially used a
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$2" Then
Application.EnableEvents = False
Call Historical_Index
Application.EnableEvents = True
End If
End Sub
And this is indeed calling my macro but only if I change B2 manually. If I wait for the data to be refreshed automatically my macro is not called (even though the data has changed).
I would like to know what to do in order to automate this process, I need your help.
Thanks in advance
Ps: I don’t know if it matters, but my macro is saved in VBAProject(“this document”) > Sheet2 (Sheet2)
Please try the below for the range B1:B8:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Sheet1.Range("B1:B8")) Is Nothing Then
Application.EnableEvents = False
Call Historical_Index
Application.EnableEvents = True
End If
End Sub
or if you want to check only B2:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Sheet1.Range("B2")) Is Nothing Then
Application.EnableEvents = False
Call Historical_Index
Application.EnableEvents = True
End If
End Sub

unlock specific area in a protected excel sheet with vba

I have to unlock a specific range (D6:BC116) in a excel sheet. It should be able for other people editing this specific area. So it should be unlocked for them.
At first I manually protect the whole sheet without any code. And after that I want to unprotect the specific area for editing. But something always goes wrong. I have these two codes. The first code has the hidden property it only hides empty cells. The other code I am trying to unprotect specific area I want to edit after protecting the whole sheet.
I am not really sure if the problem is in the first code because of the hidden property? And I am not sure if they are in a relation?
Private Sub Worksheet_Change(ByVal Target As Range)
For Each cell In Range("B6:B112")
If cell.Value <> "" Then
cell.EntireRow.Hidden = False
Else
cell.EntireRow.Hidden = True
End If
Next cell
End Sub
Sub UnlockCells()
Worksheets("Sheet1").Range("D6:BC116").Locked = False
Worksheets("Sheet1").Protect
End Sub
And when I execute this I always get "Index out of range"
Thanks!
I think you need to unprotect before unlocking.
Like this:
With Worksheets("Sheet1")
.Unprotect "MyLongAndSecurePassword"
.Range("D6:BC116").Locked = False
.Protect
End with
Concerning the first part of the code - make sure that you use a variable, which is not named cell, because cell is used by the VBEditor. Name your variable rngCell, myCell or anything else but cell. And declare it like this: Dim rngCell as Range.
Last point - lock your worksheet and try to hide and unhide manually the rows. Is it possible? If not, you know the reason for the error.
Edit:
To check whether the sheet is protected, try this in the Worksheet_Change:
Private Sub Worksheet_Change(ByVal Target As Range)
If Worksheets("Sheet1").ProtectContents Then Exit Sub
For Each cell In Range("B6:B112")
If cell.Value <> "" Then
cell.EntireRow.Hidden = False
Else
cell.EntireRow.Hidden = True
End If
Next cell
End Sub

Program excel to return a specific value

I have a spreadsheet that is going to be used in a survey.
How can I make the cells only to return "x" regardless of what the survey taker type in.
For instance, if I write a "w" in the cell, it should turn into an "x".
I have come to a point where I think there is an option when I protect the workbook or sheet. Because I can tell from another spreadsheet (which has this function) that it only works if the workbook is protected.
I tried to google it, but it seems as if I don't know the right keywords to find the answer.
Also, I have found a set of Vba code that I fiddle with, but I'm not sure this is correct. I don't want to attach the code as I don't want to confuse any response here.
Thank you for any help provided.
Put this code in the worksheet module and test it out, when you change a cell in column A (1) it will activate,
Where is the worksheet Module?
Copy and paste the code ,
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Intersect(Target, Range("A1,B1,C1,A4,B4,C4")) Is Nothing Then Exit Sub
Application.EnableEvents = 0
If Target <> "" Then Target = "X"
Application.EnableEvents = 1
End Sub
This should work for you (just change the range to the one you need) :
Option Explicit
Sub worksheet_Change(ByVal Target As Range)
On Error GoTo errorbutler 'error handler - important to have this in case your macro does a booboo
Application.Calculation = xlCalculationManual 'turn off automatic calculation to speed up the macro
Application.EnableEvents = False 'turn off events in order to prevent an endless loop
Dim LR, cell As Range 'Declare your variables
Set LR = Range("A1:b3") ' Select range of cells this macro would apply to
For Each cell In Target 'Loops through the cells that user have changed
If Union(cell, LR).Address = LR.Address Then 'Checks if the changed cell is part of your range
cell.Value="x" 'changes the value of that cell to x
End if
Next cell
Errorexit: 'part of error handling procedure
Application.EnableEvents = True 'Turn autocalc back on
Application.Calculation = xlCalculationAutomatic 'turn events back on
Exit Sub
Errorbutler: 'error handling procedure
Debug.Print Err.Number & vbNewLine & Err.Description
Resume Errorexit
End Sub
Oh yes, and this code should be put into the worksheet module - the same way as Dave has shown you