VBA to assign a cell as an array formula - arrays

I have a sheet called "Total" that I have to duplicate which contains an array formula. When I create a copy and rename it, the array formula is no longer entered as an array.
when I record a macro its looks like the following.
Range("B55").Select
Selection.FormulaArray = _
"=IF(R1C1=""Total"",INDEX('[All_File.xlsm]Sheet1'!R4C5:R8C5,MATCH(R[-53]C,'[All_File.xlsm]Sheet1'!R4C2:R8C2,0)),INDEX('[All_File.xlsm]Sheet1'!R5,MATCH(R1C1&""Groups"",'[All_File.xlsm]Sheet1'!R4&'[All_File.xlsm]Sheet1'!R3,0)))"
This issue with this is that it is referencing the file in the formula. The file reference can change so this recorded macro would not work.
Is there a way to select a cell and have it be entered as an array?
For example:
Range("B55").Select
Selection.FormulaArray
the cell is being selected and entered as an array. Again my issue with the recorded macro is that it is storing the file name, which will change, so the recorded macro cant be used again.

You can replace the file name before adding the formula:
Dim f As String, myFile
f = "=IF(R1C1=""Total"",INDEX('[{file}]Sheet1'!R4C5:R8C5,MATCH(R[-53]C," & _
"'[{file}]Sheet1'!R4C2:R8C2,0)),INDEX('[{file}]Sheet1'!R5," & _
"MATCH(R1C1&""Groups"",'[{file}]Sheet1'!R4&'[{file}]Sheet1'!R3,0)))"
myFile = 'get your filename here...
Range("B55").FormulaArray = Replace(f, "{file}", theFilename)

Related

Array of 600+ Strings in excel VBA

I am doing a loop for each string in an array such that
filename = Array(file1,file2.....file600)
However VBA gets a compile error that is due to the array taking up 8 lines. As far as I am aware it only allows 1 line
(error says expected list or separator)
I am new to VBA sorry
You can escape new lines in VBA with _.
so your solution might look like
filename = Array("file1", _
"file2", _
"file3")
See How to break long string to multiple lines and If Statement With Multiple Lines
If you have 100's of names, however, you might be better off storing them in a worksheet and reading them in, rather than hard-coding them.
Should you strings in the array be actually "buildable" following a pattern (like per your examples: "file1", "file2", ...,"file600") then you could have a Function define them for you, like follows:
Function GetFileNames(nFiles As Long) As String()
Dim iFile As Long
ReDim filenames(1 To nFiles) As String
For iFile = 1 To nFiles
filenames(iFile) = "file" & iFile
Next
GetFileNames = filenames
End Function
which you'd call in your "main" code as follows
Sub main()
Dim filenames() As String
filenames = GetFileNames(600) '<--| this way'filenames' array gets filled with 600 hundred values like "file1", "file2" and so on
End Sub
The amount of code that can be loaded into a form, class, or standard module is limited to 65,534 lines. A single line of code can consist of up to 1023 bytes. Up to 256 blank spaces can precede the actual text on a single line, and no more than twenty-four line-continuation characters ( _) can be included in a single logical line.
From VB6's Help.
when programming, you don't build an array this big mannually, never.
either you store each multiline-string inside a Cell, and at the end you buid the array like this :
option Explicit
Sub ArrayBuild ()
Dim Filenames() 'as variant , and yes i presume when using multi files, the variable name should have an "s"
With Thisworkbook.sheets("temp") 'or other name of sheet
Max = .cells(.rows.count,1).end(xlup).row '=max number of rows in column 1
Filenames = .range( .cells(1,1) , .cells(Max,1)).value2 ' this example uses a one column range from a1 to a[max] , but you could also use a multi column by changing the second .cells to `.cells(Max, ColMax)`
end with
'do stuff
erase Filenames 'free memory
End Sub
An other way is to build an array like you build a house by adding one brick at a time, like this :
Dim Filenames() as string 'this time you can declare as string, but not in the previous example
Dim i& 'counter
For i=1 to Max 'same max as in previous example, adapt code plz...
redim Preserve Filenames (1 to ubound(filenames)+1) 'this is an example for unknown size array wich grows, but in your case you know the size (here Max, so you could declare it `Dim Filenames (1 to Max)` from the start, just wanted to show every option here.
Filenames(i) = Cells (i,1).value2 'for example, but can be anything else. Also i'm beeing lazy and did not reference the cell to its sheet, wich i'd never do in actual coding...
next i
EDIT i did re-read your Question, and it is even easier (basically because you ommited the bracets in your post and corrected it as comment...), use
user3598756 's code plz. I thought File1 is a variable, when it should be written as "File1" .
EDIT 2 why bother build and array where Filename(x)="Filex" anyway? you know the result beforehand

2D array from text file in excel VBA

I am opening a text file which contains text like this
asdf,zxcv,asdwqe,asdh,we5,dvsew,safhc
asdf8,asdf3,asdf4,asdf5,asdf6,asdf7,asdf2
....
I am trying to put this all into a 2d array, the only way I have been able to do anything with this so far is to read the file line by line and split that line with a comma into a 1D array and use the information that way. But I have no idea how I'm supposed to do this with a 2D array, I have googled and have found nothing that is helpful.
is there a way I can put my 1d array into a 2d array or something?
Also I do not know how many strings there are per line(but all lines will have the same amount) nor how many lines there are in the file.
EDIT: To clarify, how I want it to work is for example if I do MsgBox myArray(1,3) I want "asdf5" to be displayed in that message box.
This should work :
Sub arrayTest()
Dim arrData
Dim wbtemp As Workbook
'/ 2 = Comma (format parameter)
Set wbtemp = Workbooks.Open("C:\temp\test.txt", False, True, 2)
'/ Read in Array. range array is always 2D
arrData = wbtemp.Worksheets(1).UsedRange
wbtemp.Close (0)
'/ Range array will always start from 1. No 0 base,
'/ but given how less code one needs to write, its a fair trade off.
MsgBox arrData(2, 4)
End Sub

VBA Associative Arrays (How to Index)

I'm a newbie to VBA so please forgive my lack of experience.
Im using excel VBA and trying to figure out how to index an array. I'm importing a CSV and using the split function. I need to access each individual items of the items split into the array(s). The best way to explain what I need is an example like this from Actionscript:
var a:Array = [];
a[1] = "Hello";
a[2] = "World";
(Except that what I have is a dynamic array created by the SPLIT function)
Where I could access "Hello" with the var a[1]
Here is what I have so far:
Sub getTxtfile()
FilePath = Application.GetOpenFilename _
(Title:="Please choose a file to open", _
FileFilter:="CSV Files *.csv* (*.csv*),")
Open FilePath For Input As #1
row_number = 0
Do Until EOF(1)
Line Input #1, LineFromFile
LineItems = Split(LineFromFile, ",")
'ActiveCell.Offset(row_number, 0).Value = LineItems(1)
'ActiveCell.Offset(row_number, 1).Value = LineItems(0)
row_number = row_number + 1
'Debug.Print LineItems(0) & ": " & LineItems(1)
Loop
Close #1
End Sub
I now have 2 arrays (LineItems(0) & LineItems(1)) but how do I index what is inside of them at this point?
Thanks for any and all help, it is greatly appreciated.
Mike
The CSV I'm using is formatted to use with other applications SolidWorks, python, etc.) besides Excel. I need to access only certain elements within the array to populate certain cells. As it is...I can pull the entire array into columns but I don't want to do that, just the ones I need. Here is a sample of the CSV:
0,.200
p,1.0709
q,1.167
r,1.177
s,1.216
t,1.570
u,1.5843
v,1.6883
w,1.9079
e,.2645
What I want to do is reference the letter in the first element and have the second element inserted in a certain cell: Reference "t" through an index and have "1.570" inserted.
The elements in my arrays are LineItems(0) and LineItems(1). So ideally I'm looking to reference each indexed item in an element as LineItems(1)(a) / LineItems(1-a) or something similar to that.
I think the commented-out lines in your code should actually work, at least as far as array access is concerned. (However, I may not fully understand what you are trying to accomplish. Would you please edit your question to clarify?) I do recommend adding
Option Explicit
Option Base 0
at the top of your file, and
Dim LineItems as Variant
before the Split call. That way the compiler will help you find errors.
However, If what you really want is to open a CSV, please allow me to suggest:
Dim wb as Workbook
Workbooks.OpenText Filename:="<filename>", DataType:=xlDelimited, Comma:=True
Set wb = Workbooks(Workbooks.Count)
which will give you a new workbook wb with the CSV parsed and ready to be accessed just like any other worksheet (docs on MSDN).
You can have associative arrays in VBA with Scripting.Dictionary object or the .NET System.Collections.HashTable, but that seems a bit overkill.
You can use Jagged Arrays (Arrays of Arrays) like this:
Line = "0,.200 p,1.0709 q,1.167 r,1.177 s,1.216 t,1.570 u,1.5843 v,1.6883 w,1.9079 e,.2645"
LineItems = Split(Line, ",")
Dim LineSubItems() ' has to be Variant or Variant() array
ReDim LineSubItems(0 To UBound(LineItems))
For i = 0 To UBound(LineItems)
LineSubItems(i) = Split(LineItems(i), " ")
Next
Debug.Print LineSubItems(1)(1) ' "p"

Parse an array returned from RTD in Excel

I am using an RTD formula in an Excel worksheet to receive a list of items in cell A1:
=RTD("josh.rtd",,"Letters",,"Lower")
The returned list in cell A1 is in curly bracket and delimited by semi colons. Basically, it's a one dimensional array of rows and looks like this
{"a";"b";"c";"d"}
If I copy that result, and paste the values in A2, then copy A2, select four cells from a column in a spreadsheet, such as A3:A6, and type an "=" in the formula window, and paste the result,
={"a";"b";"c";"d"}
I can hold down ctrl+shift+enter and populate each of those cells with an element of the array like this:
a
b
c
d
My question is this: is there a formula I can use to parse that original RTD formula result? I want to populate a combo box control with the elements of that array. I would love to be able to do this either in a cell formula or via VBA.
This documentation suggests that RTD returns a string. If so, the following should be able to parse it, returning the result as an array:
Function ParseArray(ArrayString As String) As Variant
Dim s As String
s = Replace(ArrayString, "{", "")
s = Replace(s, "}", "")
s = Replace(s, """", "")
ParseArray = Split(s, ";")
End Function

Delete duplicates within an array in vba Excel

I've got values inside an array and I would like to delete the values with are double entries, e.g. I have EUR,EUR,EUR,GBP,YEN and I like to remove the double euro entries within removing them from the execel spreadsheet.
Just save then in an array. The new array should look like that: EUR,GBP,YEN
After that I would like to write them to another spreadsheet.
My code so far:
Dim ArrayCurrency As Variant
RangeStart = "E2"
RangeEnd = "E"
RangeNew = RangeStart & ":" & RangeEnd & lRow
CurrencyArray = Range(RangeNew).Value
For Each element In CurrencyArray
Next element
I hope that you can help me!
Best regards
Matthias
Use Dictionary object for unique values - in the future.
For your current case, you may use RemoveDuplicates method on the range.

Resources