I am having difficulties with this code. I am trying to make it so that based on the value of cell D25 the value of F25 will change. I made the code in VBA (don’t know if this is actually the best way) and it is giving me a 424 runtime error: Object Required. Could someone please point me in the right direction?
Sub Storage_vesel_Controle()
Sheets("NSR Form").Select
If Range("D25") = "1" Then Range("F25").Select.Value = "0"
If Range("D25") = "2" Then Range("F25").Select.Value = ".95"
If Range("D25") = "3" Then Range("F25").Select.Paste = ".98"
End Sub
Also, what do I need to add to make the code "always running"... in loop I think?
Further to my comment above, I wasn't planning on posting an answer but saw few things which I think I will bring to your notice and comments wouldn't accommodate so much of text.
I would recommend not using .Select to select the sheet but work with the sheet directly (See Below code) You might also want to see this link
Sub Storage_vesel_Controle()
With Sheets("NSR Form")
Select Case .Range("D25").Value
Case 1: .Range("F25").Value = 0
Case 2: .Range("F25").Value = 0.95
Case 3: .Range("F25").Value = 0.98
End Select
End With
End Sub
EDIT:
Regarding your edit. You can use the Worksheet_Change Event to ensure that the values of F25 gets automatically updated or if you want a non VBA solution then simply use a Formula in F25
If you are interested in Worksheet_Change then see this. Else a simple formula like this in F25 will suffice your needs :)
=IF(D25=1,0,IF(D25=2,0.95,IF(D25=3, 0.98,"")))
Clean it up a little bit. Using a Select Case statement will be easier to work with than mutliple If/Then statements.
Sub Storage_vesel_Controle()
With Sheets("NSR Form")
.Activate '<this line is not actually necessary unless you want to be on the sheet.
Select Case .Range("D25").Value
Case 1
.Range("F25").Value = 0
Case 2
.Range("F25").Value = 0.95
Case 3
.Range("F25").Paste = 0.98
Case Else
'do nothing, or, modify as needed
End Select
End With
End Sub
Related
I have a macro that enables the user to double-click a given cell range on a Summary worksheet and access a hidden Data worksheet containing related data. When the user returns to the Summary worksheet, the Data worksheet is re-hidden.
The macro works perfectly for range D10:G15, but doesn't work for cell range C21:G26.
Summary worksheet:
VBA:
Private Sub Worksheet_Activate()
Dim sh As Worksheet
For Each sh In ThisWorkbook.Sheets
If sh.Name <> "Group Scorecard_Usage" Then
sh.Visible = xlSheetHidden
End If
Next sh
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Select Case Target.Address
Case "$D$10"
Sheets("John C - Total Applicants").Visible = True
Sheets("John C - Total Applicants").Activate
Case "$D$11"
Sheets("Doug D - Total Applicants").Visible = True
Sheets("Doug D - Total Applicants").Activate
Case "$D$12"
Sheets("Lesia - Total Applicants").Visible = True
Sheets("Lesia - Total Applicants").Activate
Case "$D$13"
Sheets("Jim Elder - Total Applicants").Visible = True
Sheets("Jim Elder - Total Applicants").Activate
Case "$D$14"
Sheets("Kevin Byrnes - Total Applicants").Visible = True
Sheets("Kevin Byrnes - Total Applicants").Activate
Case "$D$15"
Sheets("Chelsea W - Total Applicants").Visible = True
Sheets("Chelsea W - Total Applicants").Activate
Case "$E$10"
Sheets("Total_Candidates_Scott").Visible = True
Sheets("Total_Candidates_Scott").Activate
Case "$E$11"
Sheets("Total_Candidates_Doug").Visible = True
Sheets("Total_Candidates_Doug").Activate
Case "$E$12"
Sheets("Total_Candidates_Lesia").Visible = True
Sheets("Total_Candidates_Lesia").Activate
Case "$E$13"
Sheets("Total_Candidates_Jim Elder").Visible = True
Sheets("Total_Candidates_Jim Elder").Activate
Case "$E$14"
Sheets("Total_Candidates_Mark").Visible = True
Sheets("Total_Candidates_Mark").Activate
Case "$E$15"
Sheets("Total_Candidates_Chelsea").Visible = True
Sheets("Total_Candidates_Chelsea").Activate
Case "$G$10"
Sheets("Unreviewed Applicants - Scott Z").Visible = True
Sheets("Unreviewed Applicants - Scott Z").Activate
Case "$G$11"
Sheets("Unreviewed Applicants - Doug").Visible = True
Sheets("Unreviewed Applicants - Doug").Activate
Case "$G$12"
Sheets("Unreviewed Applicants - Lesia O").Visible = True
Sheets("Unreviewed Applicants - Lesia O").Activate
Case "$G$13"
Sheets("Unreviewed Applicants - Jim").Visible = True
Sheets("Unreviewed Applicants - Jim").Activate
Case "$G$14"
Sheets("Unreviewed Applicants - Mark").Visible = True
Sheets("Unreviewed Applicants - Mark").Activate
Case "$C$21”"
Sheets("Scott_Hires_wo_ps").Visible = True
Sheets("Scott_Hires_wo_ps").Activate
Case "$C$22”"
Sheets("Doug_Hires_wo_ps").Visible = True
Sheets("Doug_Hires_wo_ps").Activate
Case "$C$23”"
Sheets("Lesia_Hires_wo_ps").Visible = True
Sheets("Lesia_Hires_wo_ps").Activate
Case "$C$24”"
Sheets("Jim_Hires_wo_ps").Visible = True
Sheets("Jim_Hires_wo_ps").Activate
Case "$C$25”"
Sheets("Mark_Hires_wo_ps").Visible = True
Sheets("Mark_Hires_wo_ps").Activate
Case "$C$26”"
Sheets("Chelsea_Hires_wo_ps").Visible = True
Sheets("Chelsea_Hires_wo_ps").Activate
Case "$D$21”"
Sheets("Scott_non_scheduled_inpersons").Visible = True
Sheets("Scott_non_scheduled_inpersons").Activate
Case "$D$22”"
Sheets("Doug_non_scheduled_inperson").Visible = True
Sheets("Doug_non_scheduled_inperson").Activate
Case "$D$23”"
Sheets("Lesia_non_scheduled_inpersons").Visible = True
Sheets("Lesia_non_scheduled_inpersons").Activate
Case "$D$24”"
Sheets("Jim_non_scheduled_inperson").Visible = True
Sheets("Jim_non_scheduled_inperson").Activate
Case "$D$25”"
Sheets("Mark_non_scheduled_inpersons").Visible = True
Sheets("Mark_non_scheduled_inpersons").Activate
Case "$D$26”"
Sheets("Chelsea_ns_inpersons").Visible = True
Sheets("Chelsea_ns_inpersons").Activate
Case "$E$21”"
Sheets("Scott_nc_inpersons").Visible = True
Sheets("Scott_nc_inpersons").Activate
Case "$E$23”"
Sheets("Lesia_nc_inpersons").Visible = True
Sheets("Lesia_nc_inpersons").Activate
Case "$E$26”"
Sheets("Chelsea_nc_inpersons").Visible = True
Sheets("Chelsea_nc_inpersons").Activate
Case "$F$22”"
Sheets("Doug_Reference_Checks").Visible = True
Sheets("Doug_Reference_Checks").Activate
Case "$F$23”"
Sheets("Lesia_Reference_Checks").Visible = True
Sheets("Lesia_Reference_Checks").Activate
Case "$F$24”"
Sheets("Jim_Elder_Reference_Checks").Visible = True
Sheets("Jim_Elder_Reference_Checks").Activate
Case "$F$25”"
Sheets("Mark_Reference_Checks").Visible = True
Sheets("Mark_Reference_Checks").Activate
Case "$F$26”"
Sheets("Chelsea_Reference_Checks").Visible = True
Sheets("Chelsea_Reference_Checks").Activate
Case "$G$23”"
Sheets("Lesia_BGCs").Visible = True
Sheets("Lesia_BGCs").Activate
Case "$G$25”"
Sheets("Mark_BGCs").Visible = True
Sheets("Mark_BGCs").Activate
Case "$G$26”"
Sheets("Chelsea_BGCs").Visible = True
Sheets("Chelsea_BGCs").Activate
End Select
End Sub
I'm trying to get a handle on what I'm doing incorrectly. Any help would be tremendously appreciated.
You should never, ever have to write different lines of code for each bit of data you might get. This is the opposite of the purpose of coding.
I suspect there's relevant data in columns A & B that you haven't included... like perhaps, the person's name, in column A perhaps? If not, do that (insert a column if necessary). Pick a naming convention and stick with it. (ie., hyphens, underscores or spaces, not a combination) You'll save yourself (and others) a lot of headaches.
Avoid super-long sheet names. They're hidden anyway so you can make them simpler and more standard. Perhaps: APP, CAN, UNR, WOP, NSI, NCI, REF, BGC.
Why do all these sheets need to be hidden? It's not preventing people from accessing them. Perhaps it's because there's just too darn many of them that it's cluttered? Instead of hiding/showing them constantly you might as well hide all the tabs with:
ActiveWindow.DisplayWorkbookTabs = False
After these changes, you could replace almost all your code with a couple lines similar to:
personName = cells(Target.Row,1)
Sheets(personname & "NSI")
I bet there are hours spent on maintaining this workbook every week. If this data is at all important, what you really should do is revamp is=t completely.
Ideally, you would move it to Microsoft Access since it's made for managing databases (as opposed to creating your own database in Excel). Even if you've never used Access, you'd still find it simpler than what you're doing here.
Short of that, at the very least: put all of this data on one tab. Excel has numerous simple to use features for filter and analyzing data that are useless when you split up the data like this. Keep it all together and make Excel do the work of display what you want, when you want. You're attempting to create functionality from scratch, that Microsoft perfected for you a long time ago. AutoFilter, Grouping, Pivot Tables could all save you so much time and make this workbook easier for everyone else to use.
It would be a good idea to learn Excel's built-in worksheet functionality inside and out before trying to get into VBA. There are a ton of great (free/easy) resources and forums out there that could help you, and I guarantee you'd be glad you did.
One indication that you might be getting ahead of yourself, happens to also be the solution your actual question..
"...works perfectly fine for range D10:G15, but doesn't work for cell range C21:G26..."
Details Matter.
So, you know something changes between G15 and C21. It makes sense to inspect that part of the code closely.
First off, there is no G15 -- but besides that, if we look closely:
...looking even closer:
Beginning there, until the end of your code, you somehow switched to the wrong type of quotation mark on half of your functions.
Final couple tips that will help prevent problems like this:
Put, as the first line of every module: Option Explicit. This will force you to properly declare and handle variables, properties, and more.
Before making changes, BACKUP. If you're making 10 major changes in a day, you should keep all 10 versions, for at least a few weeks. You'd be surprised how handy they come in, especially while learning.
Test your code after every change you make. It might seem time consuming, but this is an example of how it would have saved time in the long run.
I hope didn't sound like I'm insulting you or your work, and it's definitely not my intention to discourage you from learning, but it is very important to be 100% thorough, accurate and organized in this field, and to understand a skill completely before moving on to the next one, especially in the earlier stages. Be sure to check out some of the other great Excel forums out there too. Good luck!
Edit: Example solution
This is an example of what a difference some basic organization would make. The code below has the same functionality of all of the code in the question (except this one's bug free, error handling, and automatically adaptable to new names/reports).
Required Assumptions/Organization:
Column A contains the the manager name (worksheet name suffix): FirstName LastInitial ex. Jim E is in A13 and A24
Rows 9 & 20 are hidden and contain the "report code" (worksheet name prefix) : ex. D9 = TotApp & G20 = RefChk
Worksheets are renamed accordingly (ex: TotApp Jim E, RefChk Jim E)
Therefore we have simple logic:
worksheet prefix is always column A of the clicked row.
if row is between 10-15 then row 9 of clicked column contains suffix.
if row is between 21-26 then row 20 of clicked column contains suffix.
therefore, the entire clickable range is C10:G15 and C21:G26
Code:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim destSht As String
'make sure double-clicked cell is within range
If Application.Intersect(Range("C10:G26"), Target) Is Nothing Then
Cancel = True 'cancel the double-click
Exit Sub
End If
'find the worksheet name suffix
Select Case Target.Row
Case 10 - 15
destsht = Cells(9, Target.Column)
Case 21 - 26
destsht = Cells(20, Target.Column)
Case Else
Cancel = True 'cancel the double-click
Exit Sub
End Select
'find the worksheet name prefix
destsht = Cells(Target.Row, 1) & destsht
'Unhide & activate worksheet
With Worksheets(destsht)
.Visible = True
.Activate
End With
End Sub
Length: 700 char (compared to 4700 char) (1/7th the size of the original)
I'm using a "worksheet_selectionChange" event to fire a macro whenever a cells within certain ranges are selected.
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
Select Case Target.Cells.Offset(-???,0).Value
Case "LABEL_1"
Tenor = "2W"
Call MyLameMacro()
Case....
End Select
End Sub
Those ranges look like little matricies:
If the user selects any of the cells underneath label, I want VBA to lookup whatever the label is at the top. Using offset would work if I knew exactly how many rows up to Label, but its not constant....
Is there another way to go about that?
Thanks - KC
Barring further information about the layout ... you can use formatting to build your own search algorithm. This will slow down if it has to go through thousands of lines (find another way if your data set is that large).
You'll have to replace "labelColor" and "notLabel" with the background color of the label rows. This is assuming the above picture is accurate, and "Label" is highlighted. To find the value to replace them with, simply select the cell in question, then type "debug.print selection.interior.color" into the immediate window in VBA.
By placing the label value and the origin address in parentheses after your lame macro, you can preserve those values in the macro.
I did not test this. In order to do so I would have to guess at the setup of your workbook ... but an approximation of this code should work for you.
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim i As Integer
i = 0
searchLoop:
If i > 100 Then
MsgBox ("Infinite loop. Click OK to stop")
Exit Sub
End If
If Target.Offset([-i], 0).Interior.Color = labelColor Then Call MyLameMacro(Target.Offset([-i], 0), Target.address)
If Target.Offset([-i], 0).Interior.Color = notLabel Then
If Target.Offset([-i], 0).Value = "Value" Then Call MyLameMacro(Target.Offset([-i], [-1]).Value, Target.address)
i = i + 1
GoTo searchLoop
End If
End Sub
I'm very new at VBA, so I find myself in a bit of a hazzle.
I'm trying to move a merged cell up dependent on a specific value in another cell.
Cell D4 contains a value between 1 and 4, and it is dependent on a formula.
When this value is equal to 1 I'd like for the merged cell BQ52:BX64 to move up to row 40, and not replace the cells, but shift them downwards.
When the value is between 2 and 4 I'd like for the cells to shift back to their original location.
I've tried to record macros of me inserting copied cells, but I'm unsure as to how to code this in VBA and how to avoid a loop, since I'm deleting the cells in the recording.
The name of the sheet is "Print Layout"
Any help is much appreciated!
Sub random()
If Range("D4").Value = 1 Then
Range("BQ52:BX64").Cut
Range("BQ40").Select
Selection.Insert Shift:=xlDown
End If
End Sub
This will put the merged cell at row 40 if d4 = 1 otherwise the merged cell will remain there.
If you can name your sheet in VBA something like Print_Layout in the properties window this may help avoid issues in the future. You could then use code such as:
Sub MoveMergedCells()
Print_Layout.Select
If Range("D4") = "1" Then
Range("BQ52:BX64").Cut
Range("BQ40").Insert Shift:=xlDown
End If
End Sub
You could also add an If/Then function for values 2-4. Hope this helps :)
As per the answer given by #L Johnstone, complete code can be given as:
Sub MoveMergedCells()
Print_Layout.Select
If Range("D4") = "1" Then
Range("BQ52:BX64").Cut
Range("BQ40").Insert Shift:=xlDown
Else If Range("D4") = "2" Then
Range("BQ40:BX52").Cut
Range("BQ52").Insert Shift:-xlDown
Else If Range("D4") = "3" Then
Range("BQ40:BX52").Cut
Range("BQ52").Insert Shift:-xlDown
Else If Range("D4") = "4" Then
Range("BQ40:BX52").Cut
Range("BQ52").Insert Shift:-xlDown
End If
End Sub
I have tried my best to answer this, apologies if anything misses.
Thanks!!!
I am new to VBA and have only recently been developing my excel skills.
I have created 3 different scenarios for an investment project situation, these scenarios appear in cell "h13" as a drop down box with three options being available, best case/worst case/base case.
When you select each scenario the various outputs will change on the sheet and I have set up the following code to change the outputs and display the relevant ones according to the scenario:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$H$13" Then
ActiveSheet.Scenarios(Target.Value).Show
End If
Now, what I want to achieve is the following:
In Cell E13 I have a numeric value that is my main concern (I should note this is an NPV Formula). Every
time we change scenario this value obviously changes.
I would like
to create a summary table that is simply something like this:
Scenario 1 = x Scenario 2 = y Scenario 3 = z So Ideally what I want
to do is, when we select scenario 1 we copy the value from E13 to say
B21. When we select the next scenario E13 will obviously change,
however I would like the copied value of B21 to remain the same, and
now the new Scenario 2 value to be displayed in B22.
I have no real idea how to go about this? I have tried adding this on the bottom but the values do not remain 'static'
If Target.Cells.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("h13")) Is Nothing Then
Range("E13").Copy
Range("B21:B23").PasteSpecial xlPasteValues
End If
End Sub
Now I think I know that I need to create a reference so that it would read something like when e13=y then copy, next e13=x copy and loop? it until all outcomes have occured. Not sure how to do it though.
Any help would be appreciated, I have tried to read up on this as much as possible but I cannot really exactly pin point what I need in code terms as I am very new to this
Thanks in advance.
This solution shows the results in a "range\table" located at B20:D23 (see pictures below)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rTbl As Range, lRow As Long
Application.EnableEvents = False 'To avoid triggering again when table is updated
If Target.Address = "$H$13" Then
Rem Filters value in target range
Select Case Target.Value2
Case "Base case", "Best case", "Worst case" 'Change as required
Case Else: GoTo ExitTkn 'Value is not in the list then exit
End Select
Rem Show Scenario
ActiveSheet.Scenarios(Target.Value).Show
Rem Update Results
Set rTbl = Range("B21").Resize(3, 3) 'Change as required
With rTbl
lRow = WorksheetFunction.Match(Target.Value, .Columns(1), 0)
.Cells(lRow, 2).Value = Range("E13").Value2 'Updates result - Change as required
.Cells(lRow, 3).Value = Range("D13").Value2 'Updates scenario variable - Change as required
End With
End If
ExitTkn:
Application.EnableEvents = True
End Sub
Suggest to read the following pages to gain a deeper understanding of the resources used:
Select Case Statement,
With Statement
I recorded this macro to update the date range of 16 charts. But, as you can see I am getting a Run-time error.
I have looked at other threads on stackoverflow that relate to this but none come close. The darn help button on excel doesn't help either. Can you please advise? Here is the code:
ActiveSheet.ChartObjects("Chart 18").Activate
ActiveChart.Axes(xlCategory).Select
ActiveSheet.ChartObjects("Chart 18").Activate
With ActiveSheet.PivotTables("PivotTable2").PivotFields("Date")
.PivotItems("Sep-15").Visible = False
.PivotItems("Aug-14").Visible = True
End With
Here's some simple code that should get you close. You will need to change "MySheet" in this code to the name of the sheet containing the pivot table in your workbook, and your Date field must truly be text formatted in the "Mmm-YY" format.
Sub ShowThirteenDatesStartingLastMonth()
Sheets("MySheet").PivotTables("PivotTable2").PivotCache.Refresh
Dim Dt As String
With Sheets("MySheet").PivotTables("PivotTable2").PivotFields("Date")
For h = 1 To .PivotItems.Count - 1
On Error Resume Next
.PivotItems(h).Visible = False
Next h
For i = 1 To 13
On Error Resume Next
Dt = Format(DateSerial(Year(Date), Month(Date) - i, 1), "Mmm-YY")
.PivotItems(Dt).Visible = True
Next i
End With
End Sub
It's hard to know without an example of your workbook, but I would try naming the sheet rather than using "activesheet". It's also typically a bad idea to activate or select anything, and instead you should allow the code to do as much work as it can without selecting anything.
Something like this might work better:
With Sheets("MySheet").PivotTables("PivotTable2").PivotFields("Date")
.PivotItems("Sep-15").Visible = False
.PivotItems("Aug-14").Visible = True
End With
As Josh said, you should reference the exact sheet name and maybe even the exact Pivot table name.
Also, you should avoid using .Select and instead declare a variable for each pivot chart, for example.