How to Find selected Active cell highlighted with Color and copy the data provided in the cell above to some special assigned cell - vba

I am new to VBA so if somebody help me to solve my problem then I shall be really grateful as I am stuck with it.
enter image description here
Please have a look at the attached picture below and if somebody provide me code for VBA then it will be really helpful for me. Task contains following steps.
1- In row 11 dates are provided in corresponding columns. Like 16/11, 17/11, 18/11 etc.
2- From row (12 to 29) I have different tasks to do are provided.
My task is.
1- When I select any cell/ box by filling it with any color the date available in the (row 10) above that cell (automatically goes/copies) to the specified cell mentioned for that task.
For Example: I select Row 21 AQR presentation cell and highlight it by filling it with color so the date above that cell automatically goes/copies to specified cell mentioned above for AQR presentation and similarly I have to do with every cell.
Request:
I need a code that detects the active cell which is highlighted and sends the date above that cell to a specified folder mentioned for that above.
Please see the figure for more clear understanding.
I shall be grateful if somebody help me in providing the code for this.

I do not believe that an exact match on your requirement is possible; certainly I do not know how to provide an exact match. However, I believe something very similar is possible which I think is more convenient than your request.
You need to use event routines. Excel identifies “Open workbook”, “Activate worksheet”, “Change selection” and many others as events. For any Excel event, you can write a routine in VBA which Excel will execute when that event occurs.
If you open Excel’s VB Editor and click F2 you get a list of all the classes and their members. Scroll down the Classes list until you reach “Worksheet”. The list on the right will display all member of the Worksheet class. Those with a lightning symbol against them are events: Activate, BeforeDelete, BeforeDoubleClick, BeforeRightClick, Calculate and so on. If you type “excel vba worksheet before double click event” into your favourite search engine, you will get web pages that explain the event and usually give an example of a routine for the event. I find the documentation a little vague and I usually have to experiment with an unfamiliar event.
I have written event routines for the WorkBook Open event and the Worksheet Activate, Before Right Click and Selection Change events. Unfortunately, there is no “Worksheet Change Cell Colour” event so I have used the “Worksheet Before Right Click” event instead.
With the VB Editor open, you will see the Project explorer down the left hand side. If you cannot see it, click Ctrl+R. What you will see will be something like:
- VBAProject(Xxxxx.xlsm)
- Microsoft Excel Objects
Sheet1 (Kick off)
Sheet2 (Sheet2)
ThisWorkbook
You will have more worksheets, perhaps some user forms and some modules but they do not matter for the moment. If you can see a plus where I have shown a minus, click it to expand the list. I have created a copy of your kick-off worksheet which I have named “Kick off”. You probably have a different name but I will call it “Kick off”. Click “Sheet1 (Kick off)” and a white area will appear to the right. This is a code area reserved for this worksheet. There is a similar code area for every worksheet. If you click “ThisWorkbook”, you will get another code area. You can use this code area as an ordinary module but I advise against it. This code area should be reserved for certain workbook level routines.
Place this code within the ThisWorkbook code area:
Option Explicit
Sub Workbook_Open()
If ActiveSheet.Name = "Kick off" Then
Worksheets("Sheet1").Activate
Worksheets("Kick off").Activate
End If
End Sub
A routine with the name Workbook_Open in this code area will be automatically executed when the workbook is opened. Replace “Kick off” with your name for this worksheet and replace “Sheet1” with the name of any of your other worksheets.
If worksheet “Kick off” was active when the workbook was saved, its Activate routine is not executed automatically when the workbook is opened. The sole purpose of this code is to force execution of the “kick off” activate routine.
The code below all belongs in the code area for Worksheet “Kick off”. This code will not do exactly what you want so I will attempt to explain it in sufficient detail for you to adapt it to your requirements,
My code starts with some constants for rows and columns. For example:
Const RowDate As Long = 11 ' Row holding dates
Currently, you have your dates in row 11 but this could easily change as you develop your system. If you amend your worksheet so row 13 holds the dates, simply update this constant statement and your code is fully updated. So much easier than scanning your code for all uses of the literal 11.
Next I have some constants for colours. If you do not like my colours, amend these constant statements.
Next are some Dim statements. A variable declared within a routine, is destroyed when the routine exits. A variable declared outside a routine has a longer life. I do not know if these variables last until the workbook is closed or until another worksheet is activated. It does not matter; they last long enough to allow me to pass values from one call of an event routine to another call.
Next is Private Sub Worksheet_Activate(). If your users switch to another worksheet, this routine will be called automatically when they switch back. It records the position of the active cell and loads three arrays. The three arrays and their values are:
Array entries -> 0 1
RowActionSrc 16 21
RowActionDest 2 3
ColActionDest 25 25
The way these arrays are used is a common technique with experienced programmers but might be new to you. You want special actions to occur if a selection is made on row 16 or 21. These rows may change and similar actions may be required for other rows later. By having a single statement load these row numbers into an array, it is easy to change them or add to them. If a cell on row 16 is selected, you want its date copied to row 2, column 25. If a cell on row 21 is selected, you want its date copied to row 3, column 25. These destinations may not be what you want but they are easy to change so that does not matter. I have coded Worksheet_BeforeRightClick to use the numbers in these arrays to move the required dates to the required cells.
Stepping over Worksheet_BeforeRightClick for the moment, the last routine in this code is Worksheet_SelectionChange. I was not sure if this was a good idea. The functionality provided by this routine is the cause of most of the complexity in this code. I have decided to keep the functionality because I believe it is helpful and because it gives a very good demonstration of what event routines can do. This is an image of my kick off worksheet:
It is a little small but adequate for the purpose and does not exactly match yours but is close enough. The active cell is currently cell Z21. You will notice the task and date for this cell are coloured. When I first started, I found it difficult to match the active cell to its task and date. Colouring the task and the date made it much easier. This is what Worksheet_SelectionChange does. When the user moves the active cell, this routine is called automatically to remove the colouring from the old task and date and colour the new task and date. As I said, I believe this functionality is both helpful and a good demonstration of how you can use event routines to tailor the Excel experience.
Returning to Worksheet_BeforeRightClick; this is the routine that provides the functionality that is the closest match I can achieve to what you requested. As I said, there is no event based on colouring a cell. Even if there was, I am not sure I would find it convenient. I would have to select the Home tag then Fill Colour then the colour I wanted before the event would be triggered. With the Before Right Click event, I select the cell I wish to be active using the arrow keys or the mouse or F5 or however I wish. I then click the right mouse key. The event routine colours the cell with the standard colour and copies the date.
Experiment with my code. Try to work out how it achieves its objectives. Come back with questions as necessary but the more you can work out for yourself, the quicker you will develop your own skills.
Option Explicit
' I define these column and row numbers as constants in case they change.
' If they do change, one amendment here and the code is updated. If the
' literal is used in the code, you have to search for and fix every use
' to update the code.
Const ColDateFirst As Long = 3 ' The first column with a date
Const ColTaskName As Long = 1 ' Column holding task names
Const RowDate As Long = 11 ' Row holding dates
Const RowTaskFirst As Long = 12 ' First row containing tasks
' Warning: If you change any of these colours, the values are BBGGRR which
' is Excel's standard and not RRGGB which is everyone else's standard.
Const ClrCrntHeader As Long = &H99CCFF ' Tan
Const ClrSelectedCell As Long = &HFFFF& ' Yellow
' The position of the active cell is recorded in these variable so
' when the active cell changes the old position is known. This is
' necessary to correctly maintain the row and column headers. If
' the row and column headers were not highlighted, these variables
' would not be needed.
Dim ColPrev As Long
Dim RowPrev As Long
' These arrays are loaded by Worksheet_Activate(). See that routine
' for an explanation of these arrays.
Dim RowActionSrc() As Variant
Dim RowActionDest() As Variant
Dim ColActionDest() As Variant
Private Sub Worksheet_Activate()
' This routine is called when the worksheet is activated (selected)
' * If the active cell is within the monitored area, the header row and
' column will already be hightlighted. Record the current position of
' the active cell in ColPrev and RowPrev.
' * Load RowAction and ColAction arrays
' * The monitored area is ColDatFirst and right and RowTaskFirst amd down.
Application.EnableEvents = False
If ActiveCell.Row >= RowTaskFirst And ActiveCell.Column >= ColDateFirst Then
' Active cell was within the monitored area when the workbook was closed or
' the user switched to another worksheet. The appropriate row and column
' headers will still be highlighted.
ColPrev = ActiveCell.Column
RowPrev = ActiveCell.Row
Else
' The active cell was outside the monitored area. No row or column header
' is highlighted
ColPrev = 0
RowPrev = 0
End If
' If the active cell is right clicked when it is in one of the rows
' listed in RowActionSrc:
' 1) The active cell is coloured ClrSelectedCell
' 2) The date above the active cell is copied to the row and column
' specified in the cell specified by the matching positions
' in RowActionDest and ColActionDest.
RowActionSrc = VBA.Array(16, 21)
RowActionDest = VBA.Array(2, 3)
ColActionDest = VBA.Array(25, 25)
' For example:
' * If cell(16,20) is right clicked, the date in cell(11, 20) is copied
' to cell(2,25).
' * If cell(21,27) is right clicked, the date in cell(11, 27) is copied
' to cell(3,25).
Application.EnableEvents = True
End Sub
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
' * The active cell has been right clicked.
' * If the active cell is within the monitored area and if active row is
' specified in RowActionSrc, copy the data above the active cell to the
' specified destination cell.
Dim CellColoured As Range
Application.EnableEvents = False
Dim InxC As Long
If ActiveCell.Row >= RowTaskFirst And ActiveCell.Column >= ColDateFirst Then
' Active cell was within the monitored area
For InxC = 0 To UBound(RowActionSrc)
If RowActionSrc(InxC) = ActiveCell.Row Then
' The active cell is in a row for which the date above it is to be
' copied to a specified destination. In addition, the active cell is
' to be coloured
' First remove colour from any previously selected cell
Application.FindFormat.Interior.Color = ClrSelectedCell
Do While True
' What:="*" will only match cells with a value
' What:="" will match cells with or without a value
Set CellColoured = Rows(ActiveCell.Row).Find(What:="", SearchFormat:=True)
If CellColoured Is Nothing Then
Exit Do
End If
CellColoured.Interior.ColorIndex = xlNone ' Remove colour
CellColoured.Value = "" ' Remove value if any
Loop
' Colour selected cell
Cells(ActiveCell.Row, ActiveCell.Column).Interior.Color = ClrSelectedCell
' Move date for active column to specified cell
Cells(RowActionDest(InxC), ColActionDest(InxC)).Value = Cells(RowDate, ActiveCell.Column).Value
End If
Next
End If
Cancel = True ' Surpress default action for Right Click
Application.EnableEvents = True
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.EnableEvents = False
' A new cell has been selected; that is, there is a new active cell.
If ColPrev <> 0 Then
' Remove highlighting from previous task name and date
Cells(RowPrev, ColTaskName).Interior.ColorIndex = xlNone
Cells(RowDate, ColPrev).Interior.ColorIndex = xlNone
End If
If ActiveCell.Row >= RowTaskFirst And ActiveCell.Column >= ColDateFirst Then
' Active cell is within the monitored area
ColPrev = ActiveCell.Column
RowPrev = ActiveCell.Row
' Highlight task name and date
Cells(RowPrev, ColTaskName).Interior.Color = ClrCrntHeader
Cells(RowDate, ColPrev).Interior.Color = ClrCrntHeader
Else
ColPrev = 0 ' No previous active cell
RowPrev = 0
End If
Application.EnableEvents = True
End Sub
Explanation of additional functionality
The original code would colour a cell selected with a right click but would not remove the colour from a previously selected cell. The new code locates any cells in the active row coloured ClrSelectedCell (= Yellow = &HFFFF&) and removes the colour and the value if any.
Find is normally used to search for values but it is possible to search for formats. If there is any decent documentation on the format search functionality, I have failed to find it. The extra code has been developed through experimentation rather than by following official instructions. This code has been tested using Excel 2016 but I have no reason to believe it will not work with earlier versions.
The changes are the inclusion of a new variable (Dim CellColoured As Range) and the inclusion of this code just before the newly selected cell is coloured:
Application.FindFormat.Interior.Color = ClrSelectedCell
Do While True
' What:="*" will only match cells with a value
' What:="" will match cells with or without a value
Set CellColoured = Rows(ActiveCell.Row).Find(What:="", SearchFormat:=True)
If CellColoured Is Nothing Then
Exit Do
End If
CellColoured.Interior.ColorIndex = xlNone ' Remove colour
CellColoured.Value = "" ' Remove value if any
Loop
There should only be one previously coloured cell but this code loops so all previously coloured cells are cleared of colour and value.
Note: I clear the colour using ColorIndex = xlNone rather than Colour = vbWhite. If you set the colour of a cell to white, you lose the borders but you do not if you set the colour index to none.

Define a function in VBA:
Function NOTWHITE(rng As Range) As Boolean
Application.Volatile
If rng.Interior.ColorIndex = xlNone Or rng.Interior.Color = vbWhite Then
NOTWHITE = False
Else
NOTWHITE = True
End If
End Function
Then put into D12 the following formula and copy-paste to all other cells you wish to behave like that:
=IF(NOTWHITE(D12); D$11; "")
However you need to recalculate the sheet by F9 after each change.

Related

On the selection of a single cell

As in https://www.ozgrid.com/VBA/special-cells.htm the author says:
when/if one specifies only a single cell (via Selection or Range)
Excel will assume you wish to work with the entire Worksheet of cells.
My following code (See the result) does select a single cell and the .SpecialCells(xlConstants) method does operate on the entire sheet marking all the cells with a constant red. My question is, however, why selection.Value = 1000 only works only on the single selected cell ("A1"), instead of the whole worksheet (that is all the cells are filled with 1000), According to the logic applied to the .SpecialCells(xlConstants) method?
Sub stkOvflSep7()
' This sub marks red the cells with a constant
' The first cell is selected
' Some other cells are filled with constant
Dim constantCells As Range
Dim cell As Range
Worksheets("Sheet5").Cells.Clear
activesheet.Cells.Interior.Color = xlNone
Range("c1:d4").Value = 2
Range("a1").Select
ActiveCell.Select
selection.Value = 1000 ' The first cell is selected
' Set constantCells = Range("A1").SpecialCells(xlConstants)
Set constantCells = selection.SpecialCells(xlConstants)
For Each cell In constantCells
If cell.Value > 0 Then
cell.Interior.Color = vbRed ' marks red the cells with a constant
End If
Next cell
End Sub
A cell is a cell (and not the entire worksheet) for every property and method.
The speciality you quoted...
As in https://www.ozgrid.com/VBA/special-cells.htm the author says:
when/if one specifies only a single cell (via Selection or Range) Excel will assume you wish to work with the entire Worksheet of cells.
...is because in Excel you can either select a single cell or a range of cells, but you can't deselect everything. For that reason - and because searching and/or selecting specials-cells within a single cell isn't very useful - excel uses the complete sheet for these two functions (i'm not completely sure if there is another function) when only a single cell is selcted (or referenced as range). If more than one cell is selected/referenced excel uses these cells for searching. This is the same for running searches etc. manually on the sheet.
You're not really doing the same thing as the linked article, since you are assigning to a variable, rather than selecting Range("A1").SpecialCells(xlConstants).
I suspect the usedrange version would work though.

Excel VBA How to detect if something was pasted in a Worksheet

I'll start by saying that my experience with Excel and VBA is limited to what I saw in school. I have programming experience, but in other languages.
I have a file that I get every week. The structure of this file is always the same:
ID, Name, Date, Value between 1 and 4, non-relevant data.
This data is selected through the 'select all' button (top left corner of the worksheet, little triangle below the cellname in MS excel 2013) and then copied into another default file that reworks the data to show and filter it in different sheets based on the 1-4 value and the date.
My question: How do I detect when data has/is being pasted? I've tried the Worksheet.Change event, but the paste command (CTRL+V) does not trigger the Change event.
Also, how will the data be copied? Will it update Row by row, cell by cell (which direction), ...?
I know I can easily find the answer to the last question by debugging it once I can detect the copy command, but you never know if someone knows the answer.
Is there another, more easy (or better) way to do this?
More data and information can be given if needed.
Thank you for your help.
EDIT: '...has/is being copied?' changed to pasted as it should've been.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim UndoList As String
'~~> Get the undo List to capture the last action performed by user
UndoList = Application.CommandBars("Standard").Controls("&Undo").List(1)
'~~> Check if the last action was not a paste nor an autofill
If Left(UndoList, 5) = "Paste" Then
'Do stuff
End If
End Sub
This did the trick. For those who need something similar and know the size of their list #MaciejLos' answer would also work.
Worksheet_Change event will do the job if you add a formula into cell which will never be overwritten. Let's say your data are pasted into A1 cell and occupied 5 columns. So, enter below formula into 6. column and row 1.
=COUNTBLANK(A1:A1048576)
Now, you're able to handle/detect paste event ;)
I was unable to add this as a comment so I'm posting this as an answer.
#Nahbyr 's answer works when excel has "English" set as it's preferred language,
otherwise it won't work.
So after manually searching using the immediate window I was able to find out the appropiate indexes for it to work on every language.
This is the function I wrote to test if the last action was a paste action, paste or paste special.
Public Function LastActionPaste() As Boolean
' The function LastActionPaste checks if the last action made was a paste action, if so it returns TRUE
' Otherwise it returns FALSE
Dim UndoList As String
LastActionPaste = False
UndoList = Application.CommandBars(11).Controls(14).List(1)
'~~> Check if the last action was a paste or paste special
If UndoList = "Paste" Or UndoList = "Paste Special" Then
LastActionPaste = True
End If
End Function
UPDATE
So apparently the indexes are not the same on different installations of Excel, whether because they are different versions or whatsoever...
So even if the preferrred language is not English, the CommandBars.Name is still in english, BUT the Controls.Caption do change...
Now I hope that the Controls indexes do not change otherwise this won't work.
So I modified the function like this for it to work:
Public Function LastActionPaste() As Boolean
' The function LastActionPaste checks if the last action made was a paste action, if so it returns TRUE
' Otherwise it returns FALSE
Dim UndoList As String
Dim barFound As Boolean
Dim index As Long
LastActionPaste = False
index = 1
barFound = False
Do While barFound = False
If Application.CommandBars(index).name = "Standard" Then
barFound = True
Else
index = index + 1
End If
Loop
UndoList = Application.CommandBars(index).Controls(14).List(1)
'~~> Check if the last action was a paste or paste special
If UndoList = "Paste" Or UndoList = "Paste Special" Then
LastActionPaste = True
End If
End Function

Excel macro select two ranges and compare

This is a question that was asked to me in an interview. I have a excel list. It is copied to another location and then by mistake a row in the new location gets deleted.
Now I need to write a macro to compare the old and new ranges and then provide the missing data as result.
I can perhaps perform the comparison part. But the problem is I don't know how to get the selected range as input in a macro.
For eg. as soon as I select a range, it should be sent as input to the macro, then the macro should wait for another selection. As soon as I select the new range, the macro should compare and find the missing lines in new range.
Regarding the selection per mouse click you could look at the link I sent in the comments of the other answer. Selection_Change is an event which gets triggered when you change the selection of a worksheet (not only mouseclick but move-by-keys as well). The target coming in is the cell which you have selected. You can pass this as a range on to a function.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
showMsg Target
End Sub
Private Function showMsg(r As Range)
MsgBox r.Address
End Function
You can just as well use another event like BeforeDoubleClick or BeforeRightClick. Check out the events of Excel and choose the one you feel fits best.
If you only want the function to be triggered for a certain range you can filter it.
If target.column <> 1 then exit function
If you don't want the event to trigger your function each time you change a selection you can choose one cell to be the switch which gets triggered by the same event.
If target.address = "$A$1" Then Call toggleSearch()
with toggleSearch being the switching function.
This is a classical diff (and a simple one at that), you shouldn't select by hand or anything. Just sort the two lists in an identical way, then run a Sub which loops over the number of rows in the source sheet comparing each row with the same row in the target sheet. The first mismatch you get is the missing line.
This example assumes both sheets are in the same workbook but you can easily adapt it
Public Sub diffThem()
Dim src as Worksheet, trg as Worksheet
Dim r as Range, i as Integer
Set src = ThisWorkbook.Sheets("Source")
Set trg = ThisWorkbook.Sheets("Destination")
Set r = src.Range("A1")
For i = 1 to ThisWorkbook.Sheets("Source").UsedRange.Rows.Count
If r.EntireRow <> trg.Range("A" & r.Row).EntireRow Then
MsgBox("The missing row is " & r.Row)
Exit Sub
End if
Set r = r.Offset(1,0)
Next i
End Sub
If EntireRow cannot be run due to different layouts or whatever then loop the columns at that point.

VBA code that runs like goto functions: "Ctrl-[" and "F5"

Is there any VBA code that simulates the normal goto Excel function Ctrl+[ and F5?
Further elaboration with an example:
In this Problem.xlsx are two worksheets—Alpha and Beta.
I would like a code to
Do a Ctrl+[ on cell A2 of the Alpha worksheet (i.e. grab the Beta!B5 reference in the cell)
So as to jump to cell B5 of the Beta worksheet (using the Beta!B5 reference, make the jump)
Move one cell to the right, i.e. C5 of the Beta worksheet and shade that cell yellow
And finally do a F5 to go back to cell A2 of the Alpha worksheet
I have Googled for 2 hours on various keywords like goto, ctrl-[, F5, previous selection, etc. to no avail.
Additional note:
I am trying to simulate the goto functions Ctrl-[ and F5 such that any active cell (with a link to another cell in another sheet) I am on, the VBA code can perform the jump, do the color shading and jump back to the original sheet. i.e. the below codes are too restrictive
Sub JumpColourJump()
Worksheets("Beta").Range("B5").Offset(, 1).Interior.Color = vbYellow
Worksheets("Alpha").Range("A2").Select
End Sub
The code should be flexible to jump to whichever sheet in the same file or in another file that the active cell is referring to.
Most of your code can be produced by recording a macro, but the more complex parts appear to be:
Navigating to the first cell which references the selected cell - this post on superuser looks like it contains some good advice
Returning to the previous sheet - you could just take a reference to the active sheet at the start of your function, then restore it afterwards, i.e.:
Dim initalSheet As Worksheet
' Take a reference to the current sheet
Set initialSheet = ActiveSheet
' *** Perform changes here ***
' Return to the initially selected sheet
initialSheet.Select
Something like this in order to go back and forth between the pages will work.
'follow local hyperlink
Application.Goto Reference:=Worksheets("Alpha").Cells(1, 1).FormulaR1C1
'color the cell to the right
ActiveCell.Offset(0, 1).Interior.Color = vbYellow
'return using the same method
You can then use ActiveCell.Offset(row, col) to get the right cell and perform the operations, and return using the same method.
In order to return to the previous location, you could save it in a variable,
Dim returnSheet As String, returnCell As String
returnSheet = ActiveSheet.Name
returnCell = CStr(ActiveCell.Address(False, False))
'Jump to cell, do your magic
Application.Goto Reference:=Worksheets(returnSheet).Range(returnCell)
or for several jumps from cell-to-cell a class-module acting like a stack implementing push & pop functions would be ideal.

VBA Excel Coding extension and modification

I have made an assessment system for a project using Microsoft Excel and I wanted to to make it so that you could use the same drop down menus twice.
Enter the data and then for the spreadsheet to retain that data and allow you to overwrite it but still maintain the data but to be dependant on the value of a data validation drop down list.
I have been given the code for this and it works however only for a section of the spreadsheet.
I wish to have the same effect however use a different drop down menu and for it to affect a different section of the spreadsheet.
Please feel free to ask for the actual spreadsheet or code.
Here is the Code:
Option Explicit
Public Sub Worksheet_Change(ByVal Target As Range)
' This Sub is a standard VBA event handler. It is automatically invoked
' every time the content of any cell in this worksheet changes
' We are only interested if the user picks a different type of
' grade. A named range GradeType was created to name this cell.
' This allows the worksheet format to change without having to change
' this code.
If Target.Address = Sheet1.[GradeType].Address Then
' So the user doesn't see each invidual worksheet change as it happens
Application.ScreenUpdating = False
' Where the current data will be saved to
' These are in the first row, so the number of columns has
' to be determined on the fly based on how much data is there
Dim FirstSaveTo As Range
Dim LastSaveTo As Range
' Where the previous saved data will be restored from
Dim LastRestoreFrom As Range
Dim FirstRestoreFrom As Range
' Use variables to define the relevant spaces in the Save sheet
' depending on what grade type the user selected
If [GradeType] = "Attainment" Then
Set FirstSaveTo = Save.[AttainmentStart]
Set LastSaveTo = Save.[AttainmentEnd]
Set FirstRestoreFrom = Save.[EffortStart]
Set LastRestoreFrom = Save.[EffortEnd]
Else
Set FirstRestoreFrom = Save.[AttainmentStart]
Set LastRestoreFrom = Save.[AttainmentEnd]
Set FirstSaveTo = Save.[EffortStart]
Set LastSaveTo = Save.[EffortEnd]
End If
' Save current data
' Clear previously saved data
Save.Range(FirstSaveTo, LastSaveTo).EntireColumn.ClearContents
' Copy current data
Sheet1.Range(Sheet1.[AssessmentFirst], Cells(Sheet1.UsedRange.Rows.Count, Sheet1.[AssessmentLast].Column)).Copy
' Paste
FirstSaveTo.PasteSpecial xlPasteValues
' Restore saved data
' Clear current data
Sheet1.Range(Sheet1.[AssessmentFirst], Cells(Sheet1.UsedRange.Rows.Count, Sheet1.[AssessmentLast].Column)).ClearContents
' Copy saved data
Save.Range(FirstRestoreFrom, Save.Cells(Save.UsedRange.Rows.Count, LastRestoreFrom.Column)).Copy
' Paste saved data
Sheet1.[AssessmentFirst].PasteSpecial xlValues
' Deselect copy area
Application.CutCopyMode = False
' Put user back where he started
[GradeType].Select
Application.ScreenUpdating = True
End If
End Sub
Your code is getting currently applied to the Named Range GradeType.
If you want to apply your code to another drop-down list, you can change this line:
If Target.Address = Sheet1.[GradeType].Address Then
And adapt it to whatever you need (don't forget to create a new named range first).
In order to do this, have a look at:
what is a named range and how to define it
how you can learn some vba: Programming Excel and VBA: Basic Syntax and Examples Tutorial