Is there a script to bypass 50000 characters for in-cell formula? - sql

I have this (insanely) long formula I need to run in Google Sheets, and I came across the limit error:
There was a problem
Your input contains more than the maximum of 50000 characters in a single cell.
Is there a workaround for this?
my formula is:
=ARRAYFORMULA(SPLIT(QUERY({B!A1:A100; ........ ; CA!DZ1:DZ100},
"select * where Col1 is not null order by Col1 asc", 0), " "))
full formula is: pastebin.com/raw/ZCkZahpw
apologies for Pastebin... I got a few errors here too:
note 1: due to fact that it's a long formula, the output from it should be of size ~100 rows × 3 columns
note 2: so far I managed to bypass JOIN/TEXTJOIN for 50000+ characters even 500000 limits for total cells

Is there a script to bypass 50000 characters for in-cell formula?
If the length of {B!A1:A100; ........ ; CA!DZ1:DZ100} is greater than 50 thousands characters consider to build a custom function that build the array for you. You could "hard-code" the references or list them as text on a range to be read by your script.
Then, the resulting formula could look like this:
=ARRAYFORMULA(SPLIT(QUERY(MYCUSTOMFUNCTION(),
"select * where Col1 is not null order by Col1 asc", 0), " "))
or like this
=ARRAYFORMULA(SPLIT(QUERY(MYCUSTOMFUNCTION(A1:A1000),
"select * where Col1 is not null order by Col1 asc", 0), " "))
(assuming that you have 1000 references).
A custom function works because it on the Google Sheets side instead of having a formula that exceeds the cell content limit it will use just few characters and because by using good practices it's possible to make that it takes less than the 30 seconds time execution limit for them.
It's worth to note that if the MYCUSTOMFUNCTION() variant (without arguments) is used, it only will be recalculated when the spreadsheet is opened but the MYCUSTOMFUNCTION(A1:A1000) variant (with a range reference as argument) will be recalculated every time that a cell in the range reference changes.
References
Custom Functions in Google Sheets
getDataRange

UPDATE:
I managed to enter up to 323461 characters as a formula! by using CTRL + H where I replaced simple =SUM(1) formula with my huge formula from this answer: https://webapps.stackexchange.com/a/131019/186471
___________________________________________________________
after some research, it looks like there isn't any workaround to pull this of.
recommended savings that were suggested ( shortening: A!A:A, dropping: select *, asc, shortening: "where Col1!=''order by Col1") reduced it a bit and rest was split into two formulas in VR {} array solution.

Related

Extract Top 10 products from a Excel Database (Multiple criteria)

I have a database (example attached) that gets updated automatically from other 70 files on monthly bases by macro.
I would like to extract Top 10 ordered products based on various criteria.(example attached) The file will be more complex, just tried to keep it simple for demo.
I have used some formula =LARGE('Part numbers'!A3:A301,ROW(INDIRECT("1:"&ROWS('Part numbers'!A3:A301)))) & =SUMPRODUCT((Combine!B1:B10000='DATA '!Y3)*(Combine!C1:AB1=A1)*(Combine!D1:D10000=AC2),Combine!C1:AB10000)that aloud me tho get the SUM of top5 products the problem is when I use the INDEX MATCH to extract the name of the product if there are 2 same values the formula is stooping always at the first product name + I need to add a new criteria witch is the month
Thank you in advance for any suggestions
Its ok if it is macro or formula
.
Trying fixing the range by making reference using the INDIRECT-function:
=SUMPRODUCT((INDIRECT("Combine!$B$1:$B$5000")='DATA '!Y3)*(Combine!$C$1:$AB$1=$C$1)*(INDIRECT("Combine!$D$1:$D$5000")=$AC$2),INDIRECT("Combine!$C$1:$AB$5000"))
This ensures that the Range you are referencing, e.g. $B$1:$B$5000 doesn't become $B$1:$B$4999 when for example Row 2 is deleted.
maybe the pivot-table can help u?
there some autofilters to show the top x
if u want to set a dynamic filter on pivot table u can use this:
Sub UpdateFilter()
Dim m As String
m = Month(Now())
[filPivot] = m
End Sub
Issue solved more less.
The other problem that I have now is with the formula =SUMPRODUCT((Combine!$B$1:$B$5000='DATA '!Y3)*(Combine!$C$1:$AB$1=$C$1)*(Combine!$D$1:$D$5000=$AC$2),Combine!$C$1:$AB$5000) initially I have the range of the formula =5000 but every time when my database is updated this number is decreasing till it reaches =10.
My database is updated by a macro that deletes Blanks every time,I believe this could be the issue.
Any ideas how to make this =5000 range steady?

Concatenating Row Number from a match result and a Column Letter and storing the result as a Variable's Address

I'll outline the steps I'm trying to accomplish:
1) Search through a spreadsheet for an acct # via match.
2) If it exists, I'd add offset #__ cells to the right and select that cell.
3) Set the selected cell's formula to Concatenate("ColumnLetter&Match(A1:A1000"",0) + Concatenate("ColumnLetter&Match(A1:A1000"",0)
FX Debt 1,000
Fx Equity 2000
U.S Debt 4,000
U.S Loans 5,000
Recon 1 Recon 2 Diff
11111 $ Debt 0
11112 FX Debt
So, I'd search for, say account "11111" using =match(A1:1000, "11111", 0). If it exists I'd offset to the right of it and then select that cell. I'd then add a formula to the selected cell which would add Cell references.
I'm thinking it would look something alone the lines of:
If Match(A1:A1000,"11111",0)=true
Select(A&(result from match))
Offset(three to right).select
edit
So to make the next step less ambiguous I'll separate it from the rest of the code sample...First let me explain the goal with it, though. The sample data above is divided into two tables...With the first table ending, for example with the general account U.S Loans --- 5,000. The second starting with the Acct # and Recon 1. My goal is to add certain cells that contain the values (not the values themselves, I want to be able to trace back to the accounts using precedents and dependents) of the general acct's in the first table into the selected offset cell. The way I thought I'd go about this was to search for the acct name, for example "FX Debt", the same way David suggested to find the Acct #, I'd then use the similar offset method to add the cell containing 1000, so say B2, into the original offset sell to the right of the Account #.
end edit
edit 2
Dim searchRange as Range
Dim myMatch as Variant
Set searchRange = Range("A1:A1000")
myMatch = Match("11111", searchRange, 0)
If Not IsError(myMatch) Then
rng.Cells(myMatch).Offset(,3).Formula = Sum(Match("U.S Debt", searchRange, 0).Offset(,2)+(Match("U.S Debt", searchRange, 0).Offset(,2))...
End If
Does this make more sense? I'm trying to add the amounts associated with U.S Debt and U.S Loans to the master account ($ Debt).
end edit 2
1) Search through a spreadsheet for an acct # via match.
2) If it exists, I'd add offset #__ cells to the right and select that
cell.
3) Set the selected the cell's formula to
Concatenate("ColumnLetter&Match(A1:A1000"",0) +
Concatenate("ColumnLetter&Match(A1:A1000"",0)
Don't bother with Selecting the cell. It's unnecessary about 99% of the time (probably more). More detail, here:
How to avoid using Select in Excel VBA macros
Also, your Match syntax is wrong. You need to do:
=Match("11111", A1:A1000, 0)
So, putting it all together, something like:
Dim searchRange as Range
Dim myMatch as Variant
Set searchRange = Range("A1:A1000")
myMatch = Match("11111", searchRange, 0)
If Not IsError(myMatch) Then
searchRange.Cells(myMatch).Offset(,3).Formula = ...
End If
I did not attempt to interpret the formula string given below; I'm not sure I understand what it's supposed to be doing:
sum(((Column Number -->)"I" + match(A1:A1000,"",0)+("I"+match(A1:A1000,"",0))
But at the very least we can consolidate your pseudo-code using the myMatch variable:
sum(((Column Number -->)"I" + myMatch+("I"+myMatch)
(A word of caution: the + operator can be used to concatenate strings, but there are several reasons why the & operator is preferable, notably the + operator is ambiguous and defaults to a mathematical + operator when one of the arguments is a numeric type. In other words, it attempts to add a number and a string, which will invariable result in a Mismatch error)
So revise to:
sum(((Column Number -->)"I" & myMatch & ("I"& myMatch)
Even after cleaning it up, I'm still not sure what you're trying to do with the above formula, but if you can try to explain then I can probably assist.

Varying Format "Part Number" sort issue

(Current Sort Sample:)
2-1203-4
2-1206-3
2CM-
3-1610-1
3-999
…
AR3021-A-7802
AR3021-A-7802-1
B43570-
B43570-3
I am working on an 8000+ record parts list. The challenge I am running into is that different manufactures of the parts are using many varying formats for their part numbers. “Part Number” is the field I wish to sort my entire worksheet on. (There are about 10 columns of data in this worksheet.)
My methodology for attacking this challenge was to count the number of characters to the left of any “-“ and count the total number of numeric characters in the field. (I also set “Part Numbers” that started with a non-numeric character to a count value of 99 for both count calculations so those would sort after the numeric values.) From this, I was able to sort on the values to the left of the “-“ using .the MIN of the two counts. (My “Part Numbers” are in Column B and I have a header row which means that my first “Part Number” is in cell B2.)
This method worked up to a point. My challenge is that I need to subsequently sort values after the “-“ character as is illustrated by the erroneous sort of “3-1610-1” being followed by “3-999”
One of the limitations I see is that sorting with  Data  Sort only gives three columns to sort on. To sort on just the characters to the left of the “-“ is costing me those three columns. So, I am unable to repeat the whole process of counting values after the “-“ character and subsequently sorting with  Data  Sort after running the primary sort.
Has the sort of many differing formats of a field such as “Part Number” been solved? Is there a macro that can be applied to this challenge? If so, I would be grateful for your input.
This data is continuously updated with new part numbers so the goal here is to be able to add those additional part numbers to the bottom of the worksheet and use a macro to correctly resort the appended list.
For the record, I am not married to my approach. After all, it didn’t solve my challenge!
Thank you,
Darrell
Place this procedure in a standard code moule:
Public Sub PartNumberSortFormat()
Dim i&, j&, f, vIn, vOut
vIn = [b2:index(b:b,match("*",b:b,-1))]
vOut = vIn
For i = 1 To UBound(vIn)
f = Split(Replace(vIn(i, 1), " ", ""), "-")
For j = 0 To UBound(f)
If IsNumeric(f(j)) Then
f(j) = Format$(f(j), "000000")
Else
f(j) = String$(6 - Len(f(j)), "0") & f(j)
End If
Next
vOut(i, 1) = Join(f, "-")
Next
Columns(1).Insert xlToRight
[a1] = "SORT COLUMN"
[a2].Resize(UBound(vOut)) = vOut
Columns(1).EntireColumn.AutoFit
End Sub
After running the procedure, you will notice that it has inserted a new column A on your worksheet and your data has been scooted over to the right by one column.
This new column A will contain a copy of your part numbers, reformatted in such a fashion to allow normal sorting.
Now select all of the data INCLUDING this new column A and sort A-Z on column A.
After the sort, you may delete the new column A.
This works by padding all characters surrounding dashes to six zeroes.
My Thoughts:
Excel 2010 onwards lets you sort using as many columns as you like. (Not sure about 2007). Don't know which version you have!
You could use the formula SUBSTITUTE to remove all "-" from the part number then sort on the number that remains, which gives you a order more like the one you are wanting.
eg
Value =SUBSTITUTE(B2,"-","")
3-15 315
3-888 3888
3-999 3999
3-1610 31610
3-2610 32610
3-1610-1 316101
3-2610-3 326103
It's not exactly what you need though!
Combine this with other formulas (or a VBA function) to manipulate you part number to be more sortable.
You could use FIND to find the position of the first "-" and extract the numbers before it into one column.
Similarly using FIND, MID and LEN you could extract the numbers between a part number two "-".
I suspect if will be best to write a VBA function to convert a part number into a "sortable value". This might splitting the part number into it's component bits (ie each bit being the text between the "-")
(VBA function split might useful for this. It creates an array.
If you know the formats of ALL the part numbers that can be delivered, you can code accordingly.
I suspect you code will take a numbers like and convert them as shown
AB123-456-78 AB12300456007800
AB12-45-7 AB12000450007000
AB12-45 AB12000450000000
ie padding with zeros each component of the part number
The key to sorting the TEXTUAL values into the order you want is understanding how textuals values get sorted! Do some experiments. Then create zero (or "9") padded numbers that sort the numbers as you required.
I hope this helps.
While not a technical answer to the Excel question, I am a logistician working with extremely large data sets of part numbers - always varying in format. The standard approach used in my field is to "ignore" (remove) special characters from the P/N and append the (clean) P/N to the 5-digit CAGE (manufacturer) code to create a "unique" CAGE + (clean) P/N code for sorting, lookup, etc. Create a column for that construct.

Check the length of data in a cell and add a zero

I have a spreadsheet containing data in the following format:
Col1 Col2
ROW1: 21211 Customer 3873721
ROW2: 101111 Customer 2321422
ROW3: 91214 Customer 2834712
ROW4: 231014 Customer 3729123
I need to be able to create a macro that goes through each row and determines the number of characters that make up the row1 data.
For example:
If data contained in the first cell or ROW1 consisted of a total of 6
characters then this will remain the same. If it consisted of 5
characters then a zero needs to be added to the front of it.
I'm using Excel 2003.
VBA is not needed in this case. A simple IF Statement should do the trick. Assuming the column you want to evalutate is column A place this in column B and duplicate down the column:
=+IF(LEN(A1)=5,"0" & A1,A1)
This will work provided all values are 5 or 6 characters long as it appears in your sample data.
It seems OP may be happy with a Custom Format of:
#000000
This is easy to apply but mainly may be a good idea because most other ways of prepending a 0 are only possible by conversion of numeric values to strings (as otherwise Excel will automatically strip leading zeros). If that is done selectively (for length 5 but not length 6) a column of what appears to be numbers might end up with mixed types (of different behaviour) and so confuse or inconvenience.

VBA conditional cell selection

I was having a play around with excel 2007 VBA and was hoping to create a Macro that generates a random number, then outputs a string based on the number generated. For example,
Number String
1 Athena
2 Belerephone
3 Castor
4 Dionysos
If the random number is 4, the output would be Dionysos, 1 would be Athena and so on.
Basically, I want the Macro to search through the "Number" column, find the cell that matches the randomly generated number, then output the string in the cell to its right.
I have a table of a similar nature in my Excel worksheet.
So far I have not had much success at doing this, any thoughts?
With your data in A1 thru B4, use:
=VLOOKUP(RANDBETWEEN(1,4),A1:B4,2,FALSE) or its VBA equivalent
EDIT#1 :
With the upper bound of the table stored in cell D3 :
=VLOOKUP(RANDBETWEEN(1,D3),INDIRECT("A1:B" & D3),2,FALSE)
You can use application.worksheetfunction.vlookup to perform a vlookup within your macro, and use the 1+Int(10 * Rnd()) function to return random numbers from 1 to 10 (and possibly 11, but statistically unlikely).