VBA Excel Percent format in an array - arrays

Is there a way to save a specific format in an array? I'm trying to find the percent difference and the regular difference between numbers in two separate grids. I can do these things individually but when I try to put the answer in the same worksheet I run into errors.
As of now, I calculate the percent difference and then I select the grid where all my answers are and change the style and number format. However, when I try to show the difference as well (such as "percent difference / difference" the program returns a long decimal for the percent difference. I know that the reason is because the number format and style format are not saved into the actual array but I can't figure out how to fix it.
I've tried the following:
Changing the format right before I create the slash and the difference
Assigning the answer array to the current values in the active cell (the values are still the decimals, not the percent counterparts)
Calculating percent difference and the difference, then changing the format (this was more of a faint hope than an actual attempt to change anything)
I can't remember if I tried anything else but I know it failed horribly.
***** Example ******
The user will send my program to a specific workbook that has two sheets with a grid of numbers on them. These grids have the exact same dimensions. My program will calculate the difference between these sheets (Sheet1 - Sheet2), the percent difference ((Sheet1 - Sheet2) / Sheet2), and both. These three calculations are presented on three separate sheets that the program creates. All of the numbers that the program produces will be in the cells that correspond to the cells where it got the numbers in the first place. Also, the third sheet (both percent and difference) are seen as "percent difference / difference". Now here's an example with test numbers.
Grid 1
12.0 5.0
2.0 10.0
Grid 2
6.0 7.0
1.0 3.0
Diff
6.0 -2.0
1.0 7.0
Percent Diff
100.00% -28.57%
100.00% 233.33%
So the "Both" tab would look like:
100.00%/6.0 -28.57/-2.0
100.00%/1.0 233.33%/7.0
Sorry for not making this more grid like. I wasn't sure how to present it.
Thank you

Not sure if I completely follow, but I think you may just need the range object ".Text" method:
dim rgNumValues as Range ' cells formatted as 12.0, 5.0 etc
dim rgPctValues as Range ' cells formatted as 100%, -28.57% etc.
Then to create new cells that marry both formats
dim rgNumAndPct as Range
rgNumAndPct.Cells(1,1) = rgNumValues.Cells(1,1).Text + " / " _
+ rgPctValues.Cells(1,1).Text
' creates cells w string values like "12.0 / 100%", "5.0 / -28.57%" etc.
The ".Text" method extracts the visible string from your NumValues and PctValues rather than the underlying numeric value. Just rewrite as a loop to do all the cells. For a very large range, you can speed up by creating NumAndPct values in a variant array and assigning the array to the target range.

If you are doing this with code in vba you would use the Format function for each item and append the cells in a similar fashion. If a simple formulaic version would work, something like this, substituting the sheet names in where needed.

Related

Makearray function in Office Excel unable to generate proper amount of columns for the array

I am using Office 365 currently and I want to make a visualization tools using MAKEARRAY functions.
For example, if I want to display sequential of 32 items, I would display it in this way:
I use the following formula of Makearray to generate the custom array for me
Note: Formula is pasted at cell value F3 .
=MAKEARRAY(ROUNDUP(B2/B3,0),IF(E3#=ROUNDUP(B2/B3,0),MOD(B2,B3),B3),LAMBDA(row,col,"O"))
but it seems like after debugging, this part of the formula are giving it the problem are these
IF(E3#=ROUNDUP(B2/B3,0),MOD(B2,B3),B3)
as I debugging the formula separately as shown in picture below, it can generate the correct amount of columns as it is supposed to.
Note: Generate exactly same amount to the no of columns if row number is not matching;
Generate modulus remainder formula if row number is matching to roundup of no. of items divided by no. of columns.
But in the end, I put that problematic formula back into the MAKEARRAY function just give only a single columns, which seems like it is quite wrong.
May I know why it display single columns even though by right, it should display the correct amount of no. of columns?
What about:
Formula in C1:
=WRAPROWS(INDEX("O",SEQUENCE(A1,,,0)),A2,"")
Or rather:
=WRAPROWS(EXPAND("O",A1,,"O"),A2,"")
MAKEARRAY does not expect an array in the number of columns. It is a set number. It will iterate the number of rows and number of columns to create the array. It will always be square and not jagged.
So you need to do the math to change the value:
=MAKEARRAY(ROUNDUP(B2/B3,0),B3,LAMBDA(rw,clm,IF(10*(rw-1)+clm>B2,"","O")))
Now as soon as the space is greater than the 32 it puts in "" instead of "O"

Excel - rolling average across columns without zeros, no array

I am currently using this formula to calculate a rolling average score across 12 columns for either the last 3 or 6 months.
=SUM(SUMIFS($E$54:P54,$E$54:P54,LARGE(IF($E$54:P54>0,$E$54:P54),{1,2,3})))
This is an array formula and is entered via CTRL + SHIFT + ENTER.
The problem now is that I need to deploy my work book on older machines and those being ancient office computers (we are talking windows XP and Office 2003...), I find that the array is killing the entire workbook. Now, I have already taken steps to speed up the workbook via VBA (disabling events, manual formula calc, etc.), but I need a way to convert the above array formula into a non-array formula which is NOT counting zeros or empty cells as part of the average.
I tried this below but couldnt get it to work with the zeros / empty cells.
=SUM(OFFSET($E68,0,COUNT($E68:$P68)-IF(COUNT($E68:$P68)>3,3,COUNT($E68:$P68)),1,IF(COUNT($E68:$P68)>3,3,COUNT($E68:$P68))))
Picture of the sample data attached below.
Since an Average is a "Sum" divided by a "Count", this can be accomplished using the simplicity of non-Array formulas.This formula avoids the inclusion of both zeros and blank cells:
=IF(SUM(A2:C2)>0,SUM(A2:C2)/(COUNT(A2:C2)-COUNTIF(A2:C2,0)),0).
If the row is filled with only zero values, then it shows the actual numerical average as zero, which is correct.If you want to avoid the display of zero averages in cells, then use this slightly different formula:
=IF(SUM(A3:C3)>0,SUM(A3:C3)/(COUNT(A3:C3)-COUNTIF(A3:C3,0)),"").
Of course, you will need to adjust the cell ranges for the 6 month and YTD averages; these formulas deal with 3- month ranges.
For last 3-Month range average: =SUM(OFFSET($A3,0,COUNT($A3:$L3)-IF(COUNT($A3:$L3)>3,3,COUNT($A3:$L3)),1,IF(COUNT($A3:$L3)>3,3,COUNT($A3:$L3))))/(COUNT(OFFSET($A3,0,COUNT($A3:$L3)-IF(COUNT($A3:$L3)>3,3,COUNT($A3:$L3)),1,IF(COUNT($A3:$L3)>3,3,COUNT($A3:$L3))))-COUNTIF(OFFSET($A3,0,COUNT($A3:$L3)-IF(COUNT($A3:$L3)>3,3,COUNT($A3:$L3)),1,IF(COUNT($A3:$L3)>3,3,COUNT($A3:$L3))),0))
For last 6-month average: SUM(OFFSET($A2,0,COUNT($A2:$L2)-IF(COUNT($A2:$L2)>6,6,COUNT($A2:$L2)),1,IF(COUNT($A2:$L2)>6,6,COUNT($A2:$L2))))/(COUNT(OFFSET($A2,0,COUNT($A2:$L2)-IF(COUNT($A2:$L2)>6,6,COUNT($A2:$L2)),1,IF(COUNT($A2:$L2)>6,6,COUNT($A2:$L2))))-COUNTIF(OFFSET($A2,0,COUNT($A2:$L2)-IF(COUNT($A2:$L2)>6,6,COUNT($A2:$L2)),1,IF(COUNT($A2:$L2)>6,6,COUNT($A2:$L2))),0))
These are quite lengthy, but they exclude the zero value cells from your original non-Array formula.The data was assumed to begin in row A2:L2.

SUM with IF conditions for cells containing both strings and numbers

I've got a bigger table with one column that I want to focus on, containing designation and a number. I want to simply sum the numbers that meet the criteria based on a designation.
For the simplification, I made an exercising sheet (on the pic) where I split second column into two - one string and one numeric. Since my file is quite large with many columns that would need this it would be inconvenient.
In the left column it's easy to solve the problem, it could be even easier with simple SUMIF function, but an array SUM(IF... function is, at least I think, only viable option here.
So I solved the first table with array function, but what confuses me is how to modulate the TRUE statement. Simple replacement of C:C
with
VALUE(MID(F:F;4;4))
which would format my cells to get the numbers from string does not work that way - returns zero in E12 field. F12 is just application of string to number for last cell, F10.
THIS formula does not work, even adapting to different versions of the tool.
I could use VB but if possible anyhow I would like to avoid it since parts will be shared on mobile phones.
Any ideas? Thanks a lot!
Left table was split, right original format
The array formula which you used can be replaced by the SumIf formula like below...
=SUMIF(B:B,"B",C:C)
Also without the helper column, you can use the Sumproduct formula to achieve the desired output.
But don't refer the whole column in the formula like in the above SumIf formula.
Try this..
=SUMPRODUCT((B1:B10="B")*MID(F1:F10,FIND(",",F1:F10)+1,255)*1)
Change the ranges as per your requirement but remember to make them equal in size.

Excel array Formula that copies only cells containing a string

I would prefer to use an excel array formula (but if it can only be done in VBA, so be it) that copies ALL cells from a column array that contains specific text. The picture below shows what I am after and what I have tried. I'm getting close (thanks to similar, but different questions) but can't quite get to where I want. At the moment, I am getting only the first cell instead of all the cells. In my actual application, I am searching through about 20,000 cells and will have a few hundred search terms. I expect most search terms to give me about 8 - 12 cells with that value.
formula I am using:
=INDEX($A$4:$A$10,MATCH(FALSE,ISERROR(SEARCH($C$1,$A$4:$A$10)),0))
Spredsheet Image
To make this work efficiently, I recommend having a separate cell holding the results count (I used cell C2) which has this formula:
=COUNTIF(A:A,"*"&C1&"*")
Then in cell C4 and copied down use this array formula (The -3 is just because the header row is row 3. If the header row was row 1, it would be -1):
=IF(ROW(A1)>$C$2,"",INDEX($A$4:$A$21000,SMALL(IF(ISNUMBER(SEARCH($C$1,$A$4:$A$21000)),ROW($A$4:$A$21000)-3),ROW(C1))))
I tested this with 21000 rows of data in column A with an average of 30 results per search string and the formula is copied down for 60 cells in column C. With that much data, this takes about 1-2 seconds to finish recalculating. Recalculation time can vary widely depending on other factors in your workbook (additional formulas, nested dependencies, use of volatile functions, etc) as well as your hardware.
Alternately, you could just use the built-in Filter functionality, but I hope this helps.
You need to get the ROWS. Put this in C4 and copy down.
=IFERROR(AGGREGATE(15,6, IF(SEARCH($C$1, $A$4:$A$10)>0, ROW($A$4:$A$10)), ROW($C4)-ROW($A$4)+1), "")
Array formula so use ctrl-shift-Enter

Sumproduct formula returns a #VALUE! error when the last array refers to a column with formulas in every row. MS Excel 2010

I am trying to find an easy way to calculate commissions off of sales on multiple sheets within a workbook. Each month, I need to find the total net profit for only items sold within the specified month.
The formula I am currently using is:
=SUMPRODUCT((TEXT('Sheet Name'!$P$3:P24,"MY")=TEXT($G$4,"MY"))*'Sheet Name'!$M$3:M24)
Column P shows the Sold Date,
Column M includes a formula in each row to calculate the net profit, and
cell G4 is where I would enter the month & year I am currently working with.
I have come to the conclusion that it only gives me the #VALUE! error because of the formula in each row of Column M (example: =IF(OR(F15=0,G15=0)," ",(F15-L15)) ).
When I reference a different column (in place of Column M) that does not contain formulas it works perfectly (example: =SUMPRODUCT((TEXT('Sheet Name'!$P$3:P24,"MY")=TEXT($G$4,"MY"))*'Sheet Name'!$G$3:G24) ). Also, changing the astrisk to a comma causes the formula to calculate incorrectly and add the (--(TEXT double negative does not fix the problem.
How to I get this array to calculate without removing the formulas from Column M?
Thanks for your attention.
I presume it is giving you a #VALUE error because your formula results in text (a space) and it errors when trying to multiply a space by a number (aka True or False). I think you would be better served changing your M column formula to =IF(OR(F15=0,G15=0),0,(F15-L15)). Do you have a specific reason to not make it evaluate to 0? Also is there a reason you are converting to text to do your month/year check?
Try something like this: =SUMPRODUCT(--(MONTH('Sheet Name'!$P$3:P24)=MONTH($G$4)),--(YEAR('Sheet Name'!$P$3:P24)=YEAR($G$4)),'Sheet Name'!$M$3:M24). Of course this is dependent on entering the dates as actual dates. The -- is used to change a logical/boolean (true/false) into a 1 or 0. It won't do anything useful to text. For example, it should also work as =SUMPRODUCT((MONTH('Sheet Name'!$P$3:P24)=MONTH($G$4))*(YEAR('Sheet Name'!$P$3:P24)=YEAR($G$4))*'Sheet Name'!$M$3:M24) since the multiplication converts the truthy statements to numbers. The trick is to make sure when everything else evaluates, you have =sumproduct(numbers,numbers,numbers). Your instance is one array of =sumproduct(numbers/text).

Resources