Dynamic Range for Intentionally Showing Nothing - excel

So, I've created a dynamic range for a chart, that's all well and easy.
However, in this chart there are two lines, but I only want one of the lines to show up under certain conditions, else it displays nothing! So I've tried creating my dynamic range as follows
=IF('WorksheetName'!$M$10 ='WorksheetName'!$F$31,'WorkSheetName'!dynamic_range, #N/A)
The problem is that when I do this the chart freaks out. It gives me this error:
Your formula contains an invalid external reference to a worksheet.
Verify that the path, workbook, and range name or cell reference are
correct, and try again.
If I click "ok" half the time it shows up correctly (that is, the second line disappears and the chart adjusts accordingly) and the other half the time it glitches.
Basically, how do I create a dynamic range for graphing that the chart will understand when I want it to do NOTHING and when I want it to display the range?

You need a second source range, that's cells are just empty. Applying your approach to switch between the filled range (intended to be visible) vs. the empty range (will be invisible), shall solve the issue. Note: The chart parameter "Show empty cells as:" should be set to "Gaps". (Refer to the Hidden and Empty Cells options in the chart's Select Data dialog. This is applicable to X/Y charts mainly.)

Related

Setting Print title columns as dynamic ranges

I have 100s of pages of data that I need to print and I want to have a header and a side column on every Page that is printed.
I can do this manually by using the dynamic range that I have created but I have to manually enter the name of the range into the page layout settings. I also tried to use a macro to do this using my dynamic ranges but I get an error message when I run the following script;
Sheets("1. Paste Raw Data").Select
ActiveSheet.PageSetup.PrintTitleColumns = Sheets("1. Paste Raw Data").Range("Print_Side")
ActiveSheet.PageSetup.PrintTitleRows = Sheets("1. Paste Raw Data").Range("Print_Header")
I have also tried to use the range that is defined by excel (named Print_Titles) to change these settings when the pages are printed but it will not allow me to enter more than one dynamic range. Print_Titles is currently defined like this in name manager;
='1. Paste Raw Data'!$B:$B,'1. Paste Raw Data'!$4:$6
Is there a way of using the two dynamic ranges in to define the titles for the rows and the columns?
I am afraid what you are trying to do, is not accepted by Excel...
It allows setting of PrintTitleRows like Rows, not like a range (like your dynamic range). Excel allows setting only of the ROWSto be repeated. In case of using a range (manually selected), Excel extends the range, to include full rows. In terms of range, it accepts only a range of rows.
If you insist to use your dynamic range you can use:
ActiveSheet.PageSetup.PrintTitleRows = _
ActiveSheet.Rows(Names("Print_Header").RefersToRange.Row).Address
but it would be like you scratch your left side of your head using the right arm...
You can also proceed similarly for PrintTitleColumns, but you will obtain the same result just using of:
ActiveSheet.PageSetup.PrintTitleColumns = "$A:$A"
Even you would manually try setting of those parameters, you would observe that Excel does not allow selecting of ranges. It extends the selection to the whole row(s) or column(s) according to the setting specificity.

Gridline object... How to retrieve the reference to the worksheet?

how to retrieve the reference to the chart and to the worksheet where the chart of the gridline object is, starting from the object itself?
For example, if I have a Range object, the object.Parent is the reference to the Worksheet.
How to do it if the starting object is the gridline object of a chart embedded into a worksheet?
Thanks in advance to everyone can help to put me in the right direction
I start using the answer of the post stackoverflow.com/questions/24045305. Then I added a For.. Next cycle through the worksheets collection (I don't have only one sheet and it is not always the same Chart of interest).
Furthermore, because of the AxisTitle caption is currently meaningful for me and its value is based on a cell formula result (it can't be prefixed and formatted to be white and the rest leaved to be automatic), I solved the problem adding a textbox whose value is now the cell formula result and the AxisTitle caption contains now only the unique identifier formatted to be white.

How to set an event when zoom is changed

I am trying to set an event that it is triggered when the zoom on the sheet is changed.
In particular, I would like to make column width autofit in a range with the following code.
Range("A1:M27").Columns.AutoFit
In fact, if the zooom on the sheet change (ActiveWindow.Zoom), some cells may become #######.

Protecting the Specific Shapes and Images in Excel VBA

I have an Excel Sheet with some macros. Also, I have some navigation shapes and images on my sheet. I want users of this sheet, cannot change this shapes and images positions, can't select them and can't move them.
Is there any way to Protect some specific objects?
Regards.
I believe this is an age old question ever since Shapes were added to MS Excel and the answer to which I myself was looking for many years already.
I just found out 3 days ago, on my own, how to lock MS Excel Freeform shapes like Choropleth Map shapes from being moved around, reformatted or worst, deleted, all WITHOUT needing to lock the WorkSheet, or eventually the WorkBook.
And I think I must share my discovery with the world because everyone wants to lock their Shapes!
Steps: (I work with Excel VBA and with msoFreeform shapes mostly but I think any shape should be working and manually added shapes through Excel UI should work too and in other Office Apps as well)
1.(yourWorkSheet or )ActiveSheet.Shapes.AddChart (through VBA but MAYBE you can add chart through Excel UI and then delete the only chart)
(no need for any other parameter because we just need the chart container, "ChartObject")
2.If you don't have some already, create a shape either through Excel UI or through VBA with AddShape method or BuildFreeform on the Chart directly or on to the worksheet.
3.Copy/Paste the created shape (if created through Excel UI or through VBA on the worksheet) on to the BLANK Chart Container. (NOT drag and drop)
4.Format the ChartContainer Rectangle window as required (try "No Fill & No Outline") through VBA or Excel UI
5.There are 3 options regarding protection of a Chart
(Embedded chart here because I don't work with Chart Sheets, may be this might work with them)
source:[https://peltiertech.com/Excel/ChartsHowTo/ChartProtection.html]
But here, only the relevant 2 will be shown:
5(a)ActiveChart.ProtectFormatting = True
That protection will block any formatting changes on the Shape and the Chart via "Chart Tools Menu" or "Drawing Tools - Format Menu" or moving or resizing with mouse or deleting BUT will show the ChartContainer window upon Selection via Mouse but non-selectable via VBA
eg. yourworksheet.ChartObjects("YourChartName").Chart.ProtectFormatting=True
5(b)ActiveChart.ProtectSelection = True
That will stop the shape or the chart from being selected altogether so this is the end of story
eg. yourworksheet.ChartObjects("YourChartName").Chart.ProtectSelection=True
The best thing about this method is that the shape can still be accessible through VBA like
eg.yourworksheet.ChartObjects("YourChartName").Chart.Shapes("YourShapeName or Index").whatever
except Shape.Select which should be obvious and there is NO need to lock the Worksheet or Workbook at all.
NB:1)The interesting finding here is that the 2 protections do not replace each other (if applied one after another) but more like stacked with each other meaning if both (if you really want) were set True first and then after setting either one False, the other restriction still remains.
2)Even if selection is protected as above, the chart can still be accessible through the Selection Pane, therefore:
Application.CommandBars("Selection and Visibility").Enabled = False
and also blocking the Worksheet Export are advisable but I think these are overkill nonetheless included for completeness' sake.
Discovered and tested on MS Excel 2010 so YMMV.
Nay Lynn's answer caused my Excel to crash. Specifically with the .ProtectSelection property being enabled (using Microsoft365 Excel). . . Excel VBA's Intellisense shows the property, so it is legitimate, but everything would be fine until the chart was selected. Playing around with this idea though, I did find a great work around.
1. Place a Chart on your sheet. Make it span across the area you want to protect
(we will expand the size of this chart later).
a. Leave Fill of Chart at Default until a later step (this helps ensure the
next steps are successful).
b. Delete all the elements present for the chart (Series label, Title, Etc.)
c. Shrink the "Plot Area" box leftover to as negligible as possible.
d. CRITICAL: Right Click the chart and choose "Select Data" - use the
option to remove all the data in the boxes of this dialog, otherwise when
you select the Rectangle added below, it will show the data references as
selections in the Worksheet behind it.
2. Insert a Rectangle into the Chart. It will have the default colors.
3. Tap `Esc` to clear the selection. If you select the shape and try to move it
around, it will take precedence over the Chart itself (this is how we'll trick
Excel later).
a. Confirm this does not allow the shape to be pulled beyond the border of the
Chart.
4. Set Fill of Chart to be "No Fill"
5. Expand the Rectangle's size to match the size of the chart.
6. Set Fill of Rectangle to be a color with 100% Transparency (NOT the same as "No
Fill" - this is critical)
a. You should be able to see all of your shapes, etc, but not touch them if you
click where the rectangle was, and trying to click and drag will also fail since the
Rectangle takes selection precedence and is also bound by the chart.
7. Set the fill of the Rectangle back to a color with 0 transparency (we need to
find the edge of the shape)
8. Select the Rectangle's border and it should then select the Chart instead (you
should see the chart Format option appear).
9. Expand the Chart's border to the ends of the Excel Sheet (ensure the top left
corner sits in the top left corner of the sheet by dragging it). You can also set
the height/width to an absurd number that users will get fed up with trying to find
if you do not wish to expand it across the entire boundaries (or if there's a hard
limitation - I did not try to expand across the entire sheet, but went to "BO400"
with no issue.
a. Expand the Rectangle to fit the Chart once again if it did not expand
automatically (in my case it did, but I cannot guarantee this behavior)
b. If you have any Buttons that DO need to be clicked, place this chart
at the bottom, place all the buttons/shapes etc. that need interaction to
the top, then bring the chart up a level until all the items needing
protection are hidden.
c. Change the Transparency back to 100%
10. After you have the Chart expanded properly, you will need to use a bit of VBA
to ensure the Chart's Formatting is protected as Nay Lynn mentions. Get the
Chart's name by selecting the border, and institute some VBA Code that gets
toggled based on your needs (you might want to include an unprotect sub
as well just in case).
Example:
Sub Protect_Sheet_With_Chart ()
dim sht as Worksheet
dim chrt as Chart
Set sht = ActiveSheet
'You can use a sheet by name for the above as well - make your code robust.
Set chrt = sht.ChartObjects("ChartNameFoundFromStep10").Chart
chrt.ProtectFormatting = True
End Sub
Sub UnProtect_Sheet_With_Chart ()
dim sht as Worksheet
dim chrt as Chart
Set sht = ActiveSheet
'You can use a sheet by name for the above as well - make your code robust.
Set chrt = sht.ChartObjects("ChartNameFoundFromStep10").Chart
chrt.ProtectFormatting = False
End Sub
11. After you protect the Chart, selecting it and deleting will not
actually delete it, NOR the rectangle, so it can't be removed!
12. Protect your code somehow and you'll be set!

Excel VBA: Copying color from Cell.Interior.Color to MSForms.Label.BackColor

I have a userform in Excel 2003 which contains some MSForms.Label controls. I want to set the .BackColor property of each of these controls such that they match the color of some individual cells on a worksheet.
To do this I am reading the .Interior.Color property of those cells, converting it to hex and using that value to set the .BackColor property of the Label objects.
My problem is that the value coming out of .Interior.Color is almost always incorrect the first time it is read. I have tested this by running the following command in the VBA editor immediate window:
Print Hex([sourceCell].Interior.Color)
This command almost always gives the wrong value the first time round, but gives the correct value from the second time onwards. If I change the fill color of [sourceCell] and run the command again it will do the same thing, i.e. wrong value first time, right value second time onwards.
The cells in question are all filled with colors from the chart lines/fills color selection (i.e. the two bottom rows you can see in Excel's "Format Cells" dialog under the "Patterns" tab). These colors have been modified by me to give a custom set of colors and, tellingly, the "wrong" values seem to match Excel's defaults for the customized range of color picks (i.e. the default chart line/fill colors you get when you start a new workbook).
Has anyone else experienced this behaviour/have a workaround? When I try to read the values twice at runtime it doesn't work, i.e. it doesn't switch to the correct value. The code must be stopped and the userform reloaded to force the "correct" values to come out.
Kludge/workaround via Application.OnTime.
If I run the userform prep code to set the label objects' backcolors with the userform hidden, then set the main code to run from an immediate OnTime event (making sure to re-run the prep code as part of the OnTime) then I can force Excel to give me the correct "second time round" values when showing the form.
This works for me:
MyForm.MyControl.BackColor = Range(myrange).Interior.Color
.Interior.Color returns a Variant containing the RGB of the sampled range.
.Interior.ColorIndex always returns -4140 or something weird, probably because .ColorIndex is peculiar to Excel2003's color limitations.

Resources