I'm writing a macro in Visual Basic for PowerPoint 2010. I'd like to initialize a really big list of strings like:
big_ol_array = Array( _
"string1", _
"string2", _
"string3", _
"string4" , _
.....
"string9999" _
)
...but I get the "Too many line continuations" error in the editor. When I try to just initialize the big array with no line breaks, the VB editor can't handle such a long line (1000+) characters.
Does anyone know a good way to initialize a huge list of strings in VB?
Thanks in advance!
I don't think there's a way to do what you want. But there exist some workarounds.
For example, you could load your list of strings from a file.
That example can show you a hint :
Dim value As String = File.ReadAllText("C:\file.txt")
Also, this page talks about it : Excel macros - Too many line continuations.
To expand on freelax's answer:
You could store the string values in an external text file and read the items into an array line by line. My example (untested) early binds to the Microsoft Scripting Runtime library.
Dim arr() as string
Dim fso as New FileSystemObject
Dim fl as file
Dim ts as textstrean
Dim i as long ' counter
Set fl = fso.GetFile("c:\path\to\configfile.txt")
Set ts = fl.OpenAsTextStream(ForReading)
i = 0
Do While Not ts.AtEndOfStream
Redim Preserve arr(i) 'resize the array leaving data in place
arr(i) = ts.Readline
i = i + 1
Loop
Further Reading:
FileSystemObject
File
TextStream
Reading a text file with
vba
Redim an array
Of course, you'll probably want to be smarter about resizing the array, doubling it's size when you run out of space.
An option for a workaround might be to use the Join Command, like this:
Const ARRAY_VALUES As String = _
"string1,string2," & _
"string3,string4"
Dim big_ol_array() As String
big_ol_array() = Split(ARRAY_VALUES, ",")
This would allow you to put multiple entries on each line, and then you could use multiple lines continuations.
Or, if you really want one value per line, you could just use multiple constants, like this:
Const ARRAY_VALUES1 As String = _
"string1," & _
"string2," & _
"string3," & _
"string4,"
Const ARRAY_VALUES2 As String = _
"string5," & _
"string6," & _
"string7," & _
"string8"
Const ARRAY_VALUES As String = _
ARRAY_VALUES1 & _
sARRAY_VALUES2
Of course, you could choose a different delimiter if it conflicts with your data. In cases like this I'll use a pretty rare but readable delimiter like the bullet (•), which can be typed by holding the Alt key and typing the "0149" on the number pad. Then your code would look like this:
Const ARRAY_VALUES As String = _
"string1•string2•" & _
"string3•string4"
Dim big_ol_array() As String
big_ol_array() = Split(ARRAY_VALUES, "•")
Here's some other interesting delimiters. These will all show up in the IDE (while others will just look like a box):
§ ¸ · • ¤ « » ¦ ± _ ¯ ¨ ª ¹ ² ³ ´ ° º ¿ ¡
Get rid of the line continuation character as what GSerg posted in this link if you want to keep it simple. Same link posted by Freelex actually.
Dim bigStr As String, big_ol_array() As String
bigStr = "string1"
bigStr = bigStr & "," & "string2"
bigStr = bigStr & "," & "string3"
.
.
bigStr = bigStr & "," & "string9999"
big_ol_array() = Split(bigStr, ",")
Dim BigOlArray(1 to 99999) as String
BigOlArray(1) = "String1"
BigOlArray(2) = "String2"
or to save some typing
' Keep copy/pasting the second and third lines as needed
' then all you need to change is the string
x = 1
BigOlArray(x) = "String1"
x = x+1
BigOlArray(x) = "String2"
x = x+1
BigOlArray(x) = "String3"
x = x+1
Related
Maybe I'm overlooking the obvious, but I cant figure out how to deal with a single result in an array.
I'm using Ken Getz ahtCommonFileOpenSave API in VBA to enable selecting multiple files, using the following code.
Private Sub btn_openfiles_Click()
Dim strFilter As String
Dim strInputFileName As String
Dim strFiles() As String
Dim a As Long
strFilter = ahtAddFilterItem(strFilter, "Images (*.PNG)", "*.PNG")
strFiles = ahtCommonFileOpenSave( _
Filter:=strFilter, _
OpenFile:=True, _
InitialDir:="T:\DTP\Programs\Default\", _
DialogTitle:="Please select an input file...", _
Flags:=ahtOFN_EXPLORER + ahtOFN_ALLOWMULTISELECT)
If IsArray(strFiles) Then
For a = 0 To UBound(strFiles)
Me.test_filenames = Me.test_filenames & strFiles(a) & vbCrLf
Next a
Else
Me.test_filenames = strFiles
End If
End Sub
I know that the result is an array, because I'm setting the ahtOFN_ALLOWMULTISELECT flag. When multiple files are selected, this goes well. But if only one file is selected, an
error 13 is thrown (type mismatch on strFiles)
because the return value of ahtCommonFileOpenSave is not an array.
I may be able to force an Array type just by adding a dummy value to the array produced by ahtCommonFileOpenSave and disregard this when processing the file names in the form, but maybe there is a better solution. Anyone have a suggestion?
As I already mentioned, overlooking the obvious. Changing the variable type into variant did the trick . ahtComminFileOpenSave returns the complete array when multiple files are selected and is always a Variant type. Luuk's suggestion works too (a variant type is used by default when the variable type is omitted).
The corrected (and amended) code is like this and works like a charm!
Private Sub btn_openfiles_Click()
Dim strFilter As String
Dim strInputFileName As String
Dim varFiles As Variant
Dim a As Long
strFilter = ahtAddFilterItem(strFilter, "Images (*.PNG)", "*.PNG")
Me.test_filenames = ""
varFiles = ahtCommonFileOpenSave( _
Filter:=strFilter, _
OpenFile:=True, _
InitialDir:="T:\DTP\Programs\Default\", _
DialogTitle:="Please select an input file...", _
Flags:=ahtOFN_EXPLORER + ahtOFN_ALLOWMULTISELECT)
If IsArray(varFiles) Then
For a = 0 To UBound(varFiles)
Me.test_filenames = Me.test_filenames & varFiles(a) & vbCrLf
Next a
Else
Me.test_filenames = varFiles
End If
End Sub
I am trying to split data using VBA within word.
I have got the data using the following method
d = ActiveDocument.Tables(1).Cell(1, 1).Range.Text
This works and gets the correct data. Data for this example is
This
is
a
test
However, when I need to split the string into a list of strings using the delimiter as \n
Here is an example of the desired output
This,is,a,test
I am currently using
Dim dataTesting() As String
dataTesting() = Split(d, vbLf)
Debug.Print dataTesting(0)
However, this returns all the data and not just the first line.
Here is what I have tried within the Split function
\n
\n\r
\r
vbNewLine
vbLf
vbCr
vbCrLf
Word uses vbCr (ANSI 13) to write a "new" paragraph (created when you press ENTER) - represented in the Word UI by ¶ if the display of non-printing characters is activated.
In this case, the table cell content you show would look like this
This¶
is¶
a¶
test¶
The correct way to split an array delimited by a pilcro in Word is:
Dim d as String
d = ActiveDocument.Tables(1).Cell(1, 1).Range.Text
Dim dataTesting() As String
dataTesting() = Split(d, vbCr)
Debug.Print dataTesting(0) 'result is "This"
You can try this (regex splitter from this thread)
Sub fff()
Dim d As String
Dim dataTesting() As String
d = ActiveDocument.Tables(1).Cell(1, 1).Range.Text
dataTesting() = SplitRe(d, "\s+")
Debug.Print "1:" & dataTesting(0)
Debug.Print "2:" & dataTesting(1)
Debug.Print "3:" & dataTesting(2)
Debug.Print "4:" & dataTesting(3)
End Sub
Public Function SplitRe(Text As String, Pattern As String, Optional IgnoreCase As Boolean) As String()
Static re As Object
If re Is Nothing Then
Set re = CreateObject("VBScript.RegExp")
re.Global = True
re.MultiLine = True
End If
re.IgnoreCase = IgnoreCase
re.Pattern = Pattern
SplitRe = Strings.Split(re.Replace(Text, ChrW(-1)), ChrW(-1))
End Function
If this doesn't work, there may be strange unicode/Wprd characters in your Word doc. It may be soft breaks, for instance. You could try to not split with "\W+" in stead of "\s+". I cannot test this without your document.
Dim dataTesting() As String
dataTesting() = Split(d, vbLf)
Debug.Print dataTesting(0)
works fine and thank you very much for your example,
for why it have returned a whole array is because you have used 0 as index, in many programming languages 0 is the whole array, so the first element is ,
so in my case counting from 1 this perfectly split a string that I had troubles with.
To be more exact this is how it was used in my case
Dim dataTesting() As String
dataTesting() = Split(Document.LatheMachineSetup.Heads.Item(1).Comment, vbCrLf)
MsgBox (dataTesting(1))
And that comment is a multiline string.
Image
So this msg box returned exactly first line.
I am looking for a way to read from a feed webpage which its structure is something like
A,B,C;E,F,G;....
I want to read this data and put A B and C in the first row and put E F and G in row 2, and etc.
I was looking for a function in VBA, but most of them are for only one determiner.
I also was thinking of using string functions of VBA, which that would be the last resort! Since I must read a long string and then use a cursor (which I don't know if it is like c or not!) that probably leads to unstable performance because first I don't know the volume of data, and second I want to use it in a loop.
Could you please help me with the best solution?
feed = "A,B,C;E,F,G;...."
CSV = Replace( feed, ";", vbNewLine )
TSV = Replace( CSV , ",", vbTab )
Set do = CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}") ' this is a late bound MSForms.DataObject
do.SetText TSV
do.PutInClipboard
ActiveSheet.Paste
Sub Test()
ParseString1 "A,B,C;D,E,F;G,H,I,J,K,L"
ParseString2 "A,B,C;D,E,F;G,H,I,J,K,L"
End Sub
Sub ParseString1(data As String)
Dim clip As MSForms.DataObject
Set clip = New MSForms.DataObject
data = Replace(data, ",", vbTab)
data = Replace(data, ";", vbCrLf)
clip.SetText data
clip.PutInClipboard
Range("A" & Rows.Count).End(xlUp).Offset(1).PasteSpecial
End Sub
Sub ParseString2(data As String)
Dim aColumns, aRows
Dim x As Long
aRows = Split(data, ";")
For x = 0 To UBound(aRows)
aColumns = Split(aRows(x), ",")
Range("A" & Rows.Count).End(xlUp).Offset(1).Resize(1, UBound(aColumns) + 1) = aColumns
Next
End Sub
You'll need to set a reference to the Microsoft Forms 2.0 Object Library if you use ParseString1.
I am writing VBA code for an Excel workbook. I would like to be able to open a connection with an Access database, and then import a txt file (pipe delimited) and create a new table in the database from this txt file. I have searched everywhere but to no avail. I have only been able to find VBA code that will accomplish this from within Access itself, rather than from Excel. Please help! Thank you
Google "Open access database from excel VBA" and you'll find lots of resources. Here's the general idea though:
Dim db As Access.Application
Public Sub OpenDB()
Set db = New Access.Application
db.OpenCurrentDatabase "C:\My Documents\db2.mdb"
db.Application.Visible = True
End Sub
You can also use a data access technology like ODBC or ADODB. I'd look into those if you're planning more extensive functionality. Good luck!
I had to do this exact same problem. You have a large problem presented in a small question here, but here is my solution to the hardest hurdle. You first parse each line of the text file into an array:
Function ParseLineEntry(LineEntry As String) As Variant
'Take a text file string and parse it into individual elements in an array.
Dim NumFields As Integer, LastFieldStart As Integer
Dim LineFieldArray() As Variant
Dim i As Long, j As Long
'Determine how many delimitations there are. My data always had the format
'data1|data2|data3|...|dataN|, so there was always at least one field.
NumFields = 0
For I = 1 To Len(LineEntry)
If Mid(LineEntry, i, 1) = "|" Then NumFields = NumFields + 1
Next i
ReDim LineFieldArray(1 To NumFields)
'Parse out each element from the string and assign it into the appropriate array value
LastFieldStart = 1
For i = 1 to NumFields
For j = LastFieldStart To Len(LineEntry)
If Mid(LineEntry, j , 1) = "|" Then
LineFieldArray(i) = Mid(LineEntry, LastFieldStart, j - LastFieldStart)
LastFieldStart = j + 1
Exit For
End If
Next j
Next i
ParseLineEntry = LineFieldArray
End Function
You then use another routine to add the connection in (I am using ADODB). My format for entries was TableName|Field1Value|Field2Value|...|FieldNValue|:
Dim InsertDataCommand as String
'LineArray = array populated by ParseLineEntry
InsertDataCommand = "INSERT INTO " & LineArray(1) & " VALUES ("
For i = 2 To UBound(LineArray)
If i = UBound(LineArray) Then
InsertDataCommand = InsertDataCommand & "'" & LineArray(i) & "'" & ")"
Else
InsertDataCommand = InsertDataCommand & LineArray(i) & ", "
End If
Next i
Just keep in mind that you will have to build some case handling into this. For example, if you have an empty value (e.g. Val1|Val2||Val4) and it is a string, you can enter "" which will already be in the ParseLineEntry array. However, if you are entering this into a number column it will fail on you, you have to insert "Null" instead inside the string. Also, if you are adding any strings with an apostrophe, you will have to change it to a ''. In sum, I had to go through my lines character by character to find these issues, but the concept is demonstrated.
I built the table programmatically too using the same parsing function, but of this .csv format: TableName|Field1Name|Field1Type|Field1Size|...|.
Again, this is a big problem you are tackling, but I hope this answer helps you with the less straight forward parts.
For example, I have this string that reads "IRS150Sup2500Vup". It could also be "IRS250Sdown1250Vdown".
In my previous qn, I asked how to find a number between 2 characters. Now, I need to find the word up or down after the second S now. Since it appears between the character S and the number, how do I do it?
My code looks like this:
Dim pos, pos1,pos2 strString As String
pos = InStr(1, objFile.Name, "S") + 1
pos1 = InStr(pos, objFile.Name, "S")
pos2 = InStr(pos1, objFile.Name, ?)
pos1 returns the index of the second S. I am not sure what to place in ?
Using Regex.
Note: you need a reference to MS VBScripts Regular Expression library.
Dim r As VBScript_RegExp_55.RegExp
Dim sPattern As String, myString As String
Dim mc As VBScript_RegExp_55.MatchCollection, m As VBScript_RegExp_55.Match
myString = "IRS150Sup2500Vup"
sPattern = "\w?up+" 'searches for Sup, Vup, etc.
Set r = New VBScript_RegExp_55.RegExp
r.Pattern = sPattern
Set mc = r.Execute(myString)
For Each m In mc ' Iterate Matches collection.
MsgBox "word: '" & m.Value & "' founded at: " & m.FirstIndex & " length: " & m.Length
Next
For further information, please see:
How To Use Regular Expressions in Microsoft Visual Basic 6.0
Find and replace text by using regular expressions (Advanced)