Flexible Data Label Formatting - vba

I'm hoping to add custom data labels to a stacked bar chart in Excel 2010. Each bar will have a label value pulled from a value in the sheet which is not necessarily equal to the height of the bar itself.
The sheet I'm making is a template and has drop-down selections to change the units of the data. For example: $MM with 1 decimal point, K with 2 decimal points, $ with 0 decimal points, etc... I'm running into an issue formatting the labels to match the data formatting selections. I've tried two approaches:
Formatting the data labels themselves using VBA. Partial code below for $K with one decimal:
`With ActiveChart.SeriesCollection(x).Points(y)`
.DataLabel.Text.NumberFormat = "$#,##0.0,"
Unfortunately, the labels don't seem to read the commas and divide by one thousand, so I can't accurate display thousands or millions. A value of 1000 in the above code will display as $1,000.0 instead of the desired $1.0.
Format the values in the worksheet, and then just read them with VBA. Basically, I use conditional formatting to properly display the values on the sheet, and then read them with .DataLabel.Text = Cells(r,c)
Unfortunately, though the data is formatted correctly, the values are unchanged and the labels display with no custom formatting at all.
Is there any reasonable way to achieve my goal? I'm hoping there's a way to either (1) make commas count when changing data label number formats or (2) change the actual values of the data in my sheet based on the formatting drop-down selections (instead of just giving them custom formatting which leaves the value unchanged).
Thank you,
Lance

I think the words "conditional formatting" are your issue here: I've had problems with VBA reading the underlying format of a cell when it's conditionally formatted (admittedly, my issue was with colour, rather than number format, but I expect the reasons for it not working would be the same).
If you adopt your second approach, i.e. relying on the worksheet's format using the chart's "Linked to source" option, then on a trigger of when the drop-down option is changed, you could use VBA to set the format on the worksheet instead of using conditional formatting - then the chart would pick up whatever format you're using.

Please try this:
?Format(1000,"$#,##0.0,")
$1.000,0
?Format(1000,"$#,##0,.0")
$1,0
?Format(1234,"$#,##0,.0")
$1,2

Related

Change Style of ListBox

In Outlook 2010 I have a UserForm with a ListBox.
This ListBox has 4 columns where I show a list of attachments (the columns "File-Name", "File-Type", "File-Size" and "Target-Directory".
Unfortunately the ListBox is restricted in layout functionality, the user can not adjust the column width at runtime (so I have to specify the width of the columns by design).
Because the file path can be quiet long, I set the width of the last column to 999 Pt.
So my ListBox has a horizontal scrollbar.
I want to have the following layout changes to my ListBox:
Add column headers
Change the alignment of a column to right-aligned
Optional: allow the user to sort the list by any column
Optional: allow the user to sort change the width of any column
Optional: show a grid in the ListBox
For 1. I found some answers that this is very complicated and I should use static labels above the list instead.
This is not possible, because my ListBox can be scrolled horizontally.
Is the ListBox really so restricted or is #1 and #2 possible somehow?
I know that there are foreign components available, but I am not allowed to buy any component.
And my solution should work at my colleagues too, so they would also have to install these components.
I have been experimenting with possible solutions to your problem. I think I have taken the listbox approach as far as it will go so I will share what I have discovered.
I can find nothing on the web to suggest that anyone believes you can have listbox column headers without using property RowSource. To use RowSource, you set it to an Excel range.
I got Outlook to create an Excel workbook and to write some data to it. Unfortunately, I could not find any way of getting an Outlook user form to access an Excel range. The syntax for setting RowSource is:
ListBox1.RowSource = "Emails!A2:D20"
This is not the standard syntax for a range and I have failed to discover any method of extending it to include a workbook name.
Jonah_Hess describes an interesting approach in https://stackoverflow.com/a/43381634/973283. He has two list boxes. One is a one-line listbox that contains the headings and the other contains the data. The two listboxes are set to the same number of columns with the same widths. This gives an attractive appearance but if you scroll the data listbox, the headings listbox does not scroll with it. This is not really any different from placing labels above a single listbox.
I tried putting the headings and the data list boxes in a frame and scrolling the frame but could not get it to work. I have used frames with VB user forms but the functionality is very different so there are no lessons learnt that I could bring to a VBA user form. Perhaps someone more familiar with VBA frames could get this approach to work.
I gave up trying to get a solution in Outlook. An Excel macro can access Outlook data so I tried that approach.
I created a macro-enabled workbook. Within it, I have two forms both of which fill the screen to conceal the worksheet. The first form just says: “Please wait while I load data from Outlook”. I am not clear about the data on your form so I imported selected details from a folder full of junk emails which I wrote to a worksheet. I sized the columns for the list box to match those for the worksheet. The result was:
The text is a little small but I think it is readable. The listbox at the bottom allows me to select emails for different periods. Long ago I had problems with RowSource which meant I could change the values in the range but I could not change the size of the range. I have either managed to avoid that problem today or it was a bug that has been fixed.
You can see that the headings are displayed. The columns are a little wide but I consider them to be a reasonable first approximation. Options to change the widths would be easy to implement.
The changes you ask for:
Add column headers. Done
Change the alignment of a column to right-aligned. Possible but difficult. You would need to pad the text with an appropriate number of leading spaces.
Optional: allow the user to sort the list by any column. The data is in a worksheet so easy.
Optional: allow the user to change the width of any column. I have set the column widths at runtime to show it is possible.
Optional: show a grid in the ListBox. Not possible.
If the above is interesting, I could show you all my code and instruct you on creating the forms so you could duplicate my experiment. Alternately, I could just explain: how I imported the Outlook data to Excel, how I included the column headings and how I set the column widths.
I cannot find anything to suggest that anything better can be achieved with listboxes.
An alternative approach is to use a grid of labels. This can give an attractive appearance and one or more columns could be right-aligned. Using the Controls property of the user form, you can treat the grid as a two-dimensional array. I have used this technique long ago and found it attractive and not particularly difficult.
In order to set the alignment of a specific column to the right, trying the opposite way might help you:
Set TextAlign attribute of the listbox to "3-fmTextAlignRight".
Add spaces at the END of the each data in the column of sourcearray, which you want to align LEFT. The number of added spaces should be so large as to exceed the width of the column in which the data appears. You don't have to mind whether the number fits to the columnwidth (overflown spaces do no harm). You may prefer to use & String(30, " ") instead (30 is just for example) .
If added spaces seem to be wholly ignored (i.e. data appear right-aligned only), further add any single character (such as "_") at the end of the spaces.
This is a cosmetic solution, but works when seeing left-aligned figures is too annoying.
After doing the above, please be careful when selecting from the list (trimming the added spaces, keeping BoundColumn data intact, etc.).
This trick works for both Excel and Outlook (not sure for other applications).
Test result in Outlook VBA (...trailing 50 spaces are added to data in column 1 and 4.)
Hope this helps.

Conditional Format Based on color code

I need to conditional format background color of Columns O:Y based on the color code AF:AK, is there a conditional format formula, or VBA code I can use.
Please ignore current format on columns O:X
You can't set the background colour to match the numbers directly in those cells with conditional formatting, though it is possible using VBA.
However, it is easier to check the value of the cells using the standard Conditional formatting rules and set the colours manually. This means you can have any colour matched to any number. Of course, you can choose the correct colour to fill if this is important to the solution.
I have set this up on a sheet below. I put the conditional formatting formula in the first cell (removing the $ symbol the system puts in for you) and copy across and down.

If content in a cell is too long, show "Multiple" instead of letting the text overflow in Excel

So, I have a custom function that concatenate different cells and put a comma between words.
For example, say I have "ABCD" "BC" then, this function will
output ABCD, BC. Now the problem is that the text will overflow in a cell and overlap with the cell next to that. In order to solve this problem,
I am thinking of just replacing the concatenated word with "Multiple" if more than 3 words are combined. Is there anyway to do this in a cell?
You can do this with conditional formatting AND keep the original underlying string as a raw value for other purposes.
Select the cells with the formula and create a conditional formatting rule based on a formula.         =LEN(C2)-LEN(SUBSTITUTE(C2, ",", ""))>1 
Click Format and go to the Numbers tab. Choose Custom from the list down the left side and supply the following for the Type:         ;;;[color13]_((\multipl\e)   I've opted to also make the font dark blue (colorindex # 13) and indent from the left.
Click OK to accept the formatting and then OK again to create the new rule.
        
As you can see in the sample image above, the underlying raw value remains (shown in the formula bar) but (multiple) is displayed.
More on custom number formatting codes at Number format codes

How can I convert columns into a single, pipe-separated column without losing scientific notation?

I have used this VBA code to convert columns into pipe separated format. However, the data contains numbers in scientific notation (eg 2.000000e-01) which Excel automatically converts into 0.2 which I don't want.
I have tried changing this code:
var = Application.Transpose(Application.Transpose(rng.Value))
into
var = Application.Transpose(Application.Transpose(rng))
or even
var = Application.Transpose(Application.Transpose(rng.Text))
neither of which work. I've also tried formatting the cells all to Text (the macro then gives a Value error) or even switching off scientific notation.
How can I convert columns into a single, pipe-separated column without losing scientific notation?
Sample columns:
SAMPLE TEST 2.000000e-01 2.000000e-01
You want to concatenate text values using either the CONCATENATE function or the & operator. For the scientific notation, you want to use the TEXT function. Excel is actually storing the numbers as 0.2 but then displaying them in scientific notation.
The help for the TEXT function says:
Syntax: TEXT(value, format_text)
Display scientific notations:
To display numbers in scientific (exponential) format, use the following exponent codes in the format_text argument.E (E-, E+, e-, e+) Displays a number in scientific (exponential) format. Excel displays a number to the right of the "E" or "e" that corresponds to the number of places that the decimal point was moved. For example, if the format_text argument is "0.00E+00", Excel displays the number 12,200,000 as 1.22E+07. If you change the format_text argument to "#0.0E+0", Excel displays 12.2E+6.
So for your example, assuming the values are in cells A1:D1, use:
=A1&"|"&B1&"|"&TEXT(C1,"0.000000E+00")&"|"&TEXT(D1,"0.000000E+00")
Or in VBA, you can use the Text property of the Range object to get the contents of the cell as they are displayed. If the column width is too narrow for a date and the column shows "########" then that is what the Text property will return.
EDIT: I misread the post. This answer is for separating text from one column into many columns. OP is trying the reverse.
You use the Excel Text to Columns wizard (on the Data tab, select Text to Columns). Select your data, then run click the menu. When you get to step 3, tell Excel that you want to keep the column as Text.
If you need this done using VBA, then use the macro recorder to get the initial code which you can then tweak to fit your needs.

Number to be copied from cell with the same number format and show it as a label for a shape without any change in the number format

I have a cell in excel which contains a value, lets say 100000.
Now i want this value to have commas in between them to represent the thousands and millions i.e. 100,000. I can do this by changing the number format in the home menu.
Now i want this value to be copied from that cell and paste it as a label for a shape. When i am doing this the commas go away showing me just the numbers.
I want it to happen through VBA but this is not happening in excel itself.
Does anyone have a plausible solution for this?
In range object use Text property, like this:
Sheet1.Shapes(1).TextFrame.Characters.Text = Range("A1").Text