Returning from an array - arrays

Maybe this has been asked before, but I don't even know what to search.
I have an array in Excel of n items.
I also have a binary array of n items and for each 1 in that binary array, I want to return the item its position corresponds to in the original array. For example, let's say I have: {A, B, C, D} and {0,0,1,1}. I want to return only C and D since those are the places that have 1s.
Is there a way to do that in Excel?
Thanks.
Best,
Morris

You can use:
=INDEX({"A","B","C","D"},N(IF({1},MODE.MULT(IF({0,0,1,1},COLUMN($A:$D)*{1;1})))))
Depending on ones version this may need to be confirmed with Ctrl-Shift-Enter instead of Enter when exiting edit mode.
My version automatically spills arrays so putting it in A1 gives me the full array output spilled down.

Try the following User Defined Function:
Public Function xtract(s1 As String, binpatrn As String) As String
Dim arr1, arr2, i As Long
arr1 = Split(s1, ",")
arr2 = Split(binpatrn, ",")
For i = LBound(arr1) To UBound(arr1)
If arr2(i) = "1" Then
xtract = xtract & "," & arr1(i)
End If
Next i
If xtract = "" Then
Exit Function
Else
xtract = Mid(xtract, 2)
End If
End Function
We place the comma-separated list (without braces) in A1 and the binary list (without braces ) in B1. In C1 enter:
=xtract(A1,B1)

Related

VBA Change a 1 column array to a one dimensional array

I am loading an array from a table.
aryNonE = ActiveSheet.Range("AA1:AA" & lRowNonE - 1)
test = Array("Bob Smith", "John Davies"...)
Want to use Filter but get type mismatch on aryNonE.
test works fine
[Debug shows1
How do I get aryNonE to look like test??
Thanks
Try this way, please:
Sub test2DTo1DArray()
Dim aryNonE, lRowNonE As Long
lRowNonE = 10
aryNonE = ActiveSheet.Range("AA1:AA" & lRowNonE - 1) '2D array
aryNonE = Application.Transpose(Application.Index(aryNonE, 0, 1)) '1D array
'You can test it in this way:
Debug.Print Join(aryNonE, ",")
End Sub
In this way, it can be used to filter using an array like Criteria1...
But, if the values in the 2D array are numbers, since the Criteria array must keep only strings, the range where the array is extracted from, must preliminarily be formatted as text.

defining array from worksheet not working in filter () lines with type mismatch error

I'm using secondarray as range of cells in a worksheet (Ex. "1", "2") to exclude them as autofilter list that I'm defining in the below function in "filtercriteria".
I get "type mismatch" error in the filter (secondarray) line for some reason, but I works flawlessly when I define an array using a list of items instead. For example, if I use below line to define secondarray instead.
secondarray = ("1", "2")
I've researched similar postings and wasn't lucky, can someone help with this instance?
Thanks,
Dim secondArray As Variant
secondArray = Range("L76:M76").Value
c = 0
k = 0
count = 0
rowNumb = Worksheets("List").Range(Worksheets("List").Range("L5"), Worksheets("List").Range("L5").End(xlDown)).Rows.count
For L = 1 To rowNumb
c = Worksheets("List").Range("L5").Offset(L)
If c <> k Then
'check the current activity type against the array of types we don’t want. If it isn’t in the array we add it to an array that will be used as the filter criteria
If UBound(Filter(secondArray, c)) = -1 Then
ReDim Preserve filterCriteria(0 To count)
filterCriteria(count) = c
count = count + 1
End If
k = c
End If
Next
It isn't working because filter function takes a One-dimensional array of strings to be searched for its sourcearray argument.
When you read in a range from the sheet you automatically get a 2d array as opposed to the 1D you have when assigning from a list.
Find a way to use a 1D array to pass in
For example, as your data is coming from 1 row then slice the array by row
UBound(Filter(Application.WorksheetFunction.Index(secondArray, 1, 0), c)) = -1
You may need to find the right method for you.
Another method is given here.

Storing values into a multidimensional array

I am trying to Redim an array with multiple columns like:
Dim f() as Variant
ReDim f(0 To 0, 0 To 0) As Variant
ReDim Preserve f(0 To UBound(f), 0 To UBound(f))
To obtain something like this:
[15 34 70]
When I try to store into the array, I am doing as:
f(0,i) = ...
f(1,i) = ...
f(2,i) = ...
What's wrong with the code?
I wanted to create an array with 1 row and 3 columns where the number of columns could increase. First, I needed to re-dimension the empty array (Dim f() As Variant) as follows (ReDim f(0 To a, 0 To 3)). The above code was not working since I was trying to Redim the array that was already dimensioned.
Second, I wanted the array to return:
f(0,i) = "Bring the value from, for instance, cells A9"
f(0,i+1) = "Bring the value from, for instance, cells A16"
f(0,i+2) = "Bring the value from, for instance, cells G16"

Lookup multiple values and return a single string

I have found how to lookup multiple values and return them as a list (one value in one cell). But I need to display the found list in a single cell (as a string with break lines); preferably with a semicolon after each value.
For example:
Source list (one value - one cell):
A
A
B
B
B
C
Result (displayed in a single cell):
A;
B;
C;
Thank you!
You'll need to extract unique values and then concatenate those values.
When a2:a7 = {a, a, b, b, b, c}, type this at b2 and hit ctrl + shift + enter.
=IFERROR(INDEX($A$2:$A$7,MATCH(SUM(COUNTIF(B$1:B1,$A$2:$A$7)),COUNTIF($A$2:$A$7,"<"&$A$2:$A$7),0)),"")
Then copy b2 and paste it onto b3:b7. Now you have a list of unique values. This method is from this answer.
Now that you have the list, you only have to join them. type this at c2.
=IF(B2="", "", B2&";"&CHAR(10))
&IF(B3="", "", B3&";"&CHAR(10))
&IF(B4="", "", B4&";"&CHAR(10))
&IF(B5="", "", B5&";"&CHAR(10))
&IF(B6="", "", B6&";"&CHAR(10))
&IF(B7="", "", B7&";"&CHAR(10))
See the picture.
I know this is ulgy. But there's no built-in formula in Excel. Other workarounds without VBA are here and there, just in case.
By the way, Google Spreadsheet provides all of these as built-in functions. Just one line.
=join(";"&char(10), filter(unique(A2:A7), not(isblank(unique(A2:A7)))))&";"
Use a static dictionary object in a user defined functiuon (aka UDF) and overwrite any duplicates.
Option Explicit
Function udfUniqueList(str As String, _
delim As String, _
Optional cs As Boolean = False)
Dim a As Long, arr As Variant
Static dict As Object
If dict Is Nothing Then
Set dict = CreateObject("Scripting.Dictionary")
End If
dict.RemoveAll
dict.CompareMode = IIf(cs, vbBinaryCompare, vbTextCompare)
arr = Split(str, Chr(10))
For a = LBound(arr) To UBound(arr)
dict.Item(arr(a)) = a
Next a
udfUniqueList = Join(dict.keys, delim) & delim
End Function
A static object is best for functions that will be copied down a long column as the object does not have to be recreated for repetitious use.
Remember to turn 'wrap text' on in the destination cell.

Transform Integer Cell Range into Excel Cell Range

I am coding in Ruby / Rails, and I have a cell range, an example is:
[0,1]..[0,3] with the convention [row, column]..[row..column]
Excel uses cell ranges like:
A2:A4 with the convention <column><row>:<column><row>
I need to convert from the former to the latter.
It is mainly the letter's that I am concerned with:
A => 0,
B => 1,
C => 2,
AA => 26
AB => 27
How would I go about doing that?
I essentially need to do the reverse of this:
Generate letters to represent number using ruby?
VBA Solution
Sub test_JohnLinux()
MsgBox ColLet(4) & vbCrLf & InvColLet("D")
End Sub
Get number from letters :
Public Function InvColLet(x As String) As Long
ActiveSheet.Cells(1, x).EntireColumn.Column
End Function
Get letters from numbers :
Public Function ColLet(x As Integer) As String
With ActiveSheet.Columns(x)
ColLet = Left(.Address(False, False), InStr(.Address(False, False), ":") - 1)
End With
End Function
Ruby Solution
Credit must go to Howard, I adapted the answer from here: https://codegolf.stackexchange.com/questions/3971/generate-excel-column-name-from-index
excel_column_ref =-> array_column_ref do
ref = "A"
array_column_ref.times{ ref.next! }
ref
end
This returns a proc.
Usage excel_column_ref[26] = 'AA'

Resources