Separating a String into two - VBA [duplicate] - excel

This question already has answers here:
How to extract file name from path?
(16 answers)
Extract filename from path [duplicate]
(9 answers)
Closed 1 year ago.
Background:
I have written some VB to search through a directory for a file (the date of the file will be variable, hence the wildcard) the code will then open the file, copy a list of names to another spreadsheet, store the names in an array so I can return their relative position in the other spreadsheet - pos, I need to do this as the next part of the code writes a link to that spreadsheet.
My filename search code is as follows:
Dim lcFound As String
lcFound = Dir("C:\Users\KDelaney\Desktop\*XYZ Select XYZ List.xlsm")
If lcFound <> "" Then
Workbooks.Open Filename:=lcFound
End If
Not going to add all the code as I don't think it's relative to the question. The writing a link formula to each cell in a f loop is as below, the below code was fine before I was using the file search, as I was testing it with the full file name and path:
Cells(f, 4).Formula = "=" & "'" & lcPath & "[" & lcFile & "]" & "Template" & "'!" & "AB" & pos
Question:
Basically the question is what would be the best way to convert C:\Users\KDelaney\Desktop\*XYZ Select XYZ List.xlsm into lcPath and lcFile, or is there a way round separating the strings? (Have briefly tested it unseparated but it seems like the square brackets around the filename is required).
I'm guessing the best course of action would be using InStr function? to return the position of the end of the file path? e.g. I know the filepath will always end with "Desktop\" so if I use InStr to return that position I will then know the filepath is between 1 and the returned value of InStr. However this is where I have stalled, not sure where to go from here, in terms of separating the two strings. I also know the start of the file name will always begin with a number and end with the file extension. I am probably making a meal of this problem and someone will come back with a very simple solution (hopefully)
Any help would be appreciated. Apologies if the question was too in depth just wanted to give you the full picture.
Thanks.

Sorry for:
a) Not researching enough if the question has already been asked/answered
b) answering my own question
Link contains two good answers, a function and using file system object.
How to extract file name from path?
I am going to persevere using the split function for my own knowledge and if things don't go well I will resort to one of the other two methods in the link above.
Further edit: haven't cleaned the code up yet, but I have realised I was massively overcomplicating the problem, all it required was a bit of messy string manipulation. If anyone comes across a similar problem:
Dim WrdArray() As String
Dim lcFound As String
strPath = "C:\Users\KDelaney\Desktop\*XYZ Select XYZ List.xlsm"
newstrL = InStrRev(strPath, "\")
newstrL = newstrL - 1
strlen = Len(strPath)
lnPath = strlen - newstrL
MsgBox Left(strPath, lnPath)
Definitely not the best way of doing it, have realized there are 'multiple ways to skin a cat' in this situation.
Link below for lots of info on string manipulation:
https://www.excel-easy.com/vba/string-manipulation.html

Related

Use String text as Code in Visual Basic for Excel

For various reasons, I need to concatenate a text of the form [NAME].Value by changing the value of NAME to an inputbox entry.
Something like this:
Sub example()
data_in = InputBox("Give me something: ")
mystring1 = "[" & data_in & "].Value"
a = Evaluate(mystring1) 'I know this is wrong, but I don't know how to do so.
End Sub
I know it can be done in other ways, and the example in which I want to use this code is not exactly this one, and while it can be done in several ways here, in the original code it can only be done this way.
I want, based on the input in the imputbox, to concatenate the string in whatever way, and subsequently cast that string as code to store the value in another variable, to be used later in the code.
I am not able to get VBA to read the string text as code. I have seen that there is a way that consists of creating a macro from this first macro, execute it, and then delete the recently created macro. The problem with this solution is that doing that I can't save the variable when returning to the initial macro (I don't want to use global variables).
Surely there must be a way?
Thank you very much.
EDIT: The code above returns Error 2015
In order to use a string as if it was code, you can use the evaluate function (exists in most languages)
The official documentation mentions this example:
[a1].Value = 25
Evaluate("A1").Value = 25
trigVariable = [SIN(45)]
trigVariable = Evaluate("SIN(45)")
Set firstCellInSheet = Workbooks("BOOK1.XLS").Sheets(4).[A1]
Set firstCellInSheet = _
Workbooks("BOOK1.XLS").Sheets(4).Evaluate("A1")
I have figured out the easiest way to do it, sorry for posting the question so soon.
Thanks to #Andreas for the solution. I'll write it here in case than could be useful to someone.
Sub example()
data_in = InputBox("Give me something: ")
a = Range(data_in).Value
Debug.Print a
End Sub
In the end the simplest thing is the last thing you try...

How do I find the name of folder with wildcard matching at least one character in VBA

I am working on an Excel spreadhseet and trying to figure out how to use wildcards. I have many subfolders in a folder called Projects. I need to be able to search and find the name of a specific folder inside using the project number. So, the folder names are of the type:
5123_Smith_Croydon
4378_Cook_Manchester
and so on.
So I have the following code, which works fine:
folderLoc = "C:\PROJECTS\"
projectNum = Range("A2").Value2 'this is just a 4 digit number representing the project number
folderName = Dir(folderLoc & projectNum & "*", vbDirectory)
However, some project folder are just called:
5234_
and then the next folder would be the actual:
5234_Harvey_Glasgow
So I am looking for a way to find the second (the longer one containing the name and the city), but my code only finds the first (5234_).
I tried the following but it just does not work and I do not understand why:
folderLoc = "C:\PROJECTS\"
projectNum = Range("A2").Value2 'this is just a 4 digit number representing the project number
folderName = Dir(folderLoc & projectNum & "*[A-Z]*", vbDirectory)
Could you please help me with a wildcard combination that effectively searches for "contains at least one character after the underscore". This one character is always a capital letter if this would make it simpler.
Thank you in advance
You can't specify a class of character after the underscore, but you can specify that there IS a character after the underscore, using the ? wildcard.
Dir(folderLoc & projectNum & "_?*", vbDirectory)
If that doesn't work, then you could read in the entire directory, and process the list using more complex methods, or Regular Expressions.

Extract XBRL facts to Excel

I would like to cycle through several hundreds of XBRL-files automatically and gather certain specific pieces of data and paste them into an excel sheet. I managed to get the "tangential code" working, but cannot answer the core question.
E.g., in the XBRL file I need the value of this fact, reported against the concept pfs:GainLossBeforeTaxes:
<pfs:GainLossBeforeTaxes
unitRef="U-EUR"
decimals="INF"
contextRef="CurrentDuration">1091134.68</pfs:GainLossBeforeTaxes>
==> I need to obtain 1091134.68
This is doubtlessly something which is easy with Regex, but I cannot seem to get this working. And time constraints are also a thing for me, so I would like to obtain some sort of minimal viable product so far and later on expand that, but at this point the code is more of a means to an end, rather than the endproduct (analysis) itself.
So far, I came up with the following:
Sub EDI_Input()
Dim myFile As String
Dim textline As String
Dim StartPos As Integer
Dim EndPos As Integer
myFile = Application.GetOpenFilename()
Open myFile For Input As #EDI
Do Until EOF(EDI)
Line Input #EDI, textline
If InStr(textline, "NonRecurringFinancialCharges") <> 0 And InStr(textline, "CurrentDuration") <> 0 Then
Endpos = InStr(textline, "</pfs:NonRecurringFinancialCharges><")
result = Left(textline, Endpos - 1)
StartPos = InStr(textline, "Char(34)&CurrentDuration&Char(34)&>")
textline = Left(textline, StartPos + 18)
Debug.Print (textline)
End If
Loop
I keep stumbling on the "invalid call procedure or argument error", possible because I load to many data in my string.
Anybody who has any opinion on how to get at least a partially working programma - in that way I can at least partially start my analysis - Or a tutorial for beginners/experience with this problem?
Welcome to StackOverflow!
I recommend using an XBRL processor, for example Arelle, which is open source. If I correctly remember, you should be able to export facts to formats like CSV and import it into Excel.
Otherwise, you will end up reimplementing an XBRL processor in VBA. There are many involved details to consider in order to get the correct values (joining with context, considering dimensions, etc). Values could be reported against a concept for multiple periods, etc.
An XBRL processor will do that out of the box.

Please assist with writing a Macro to clean up data entries

Quick question that should be easy enough for a lot of you but I'm not well versed in VBA or code in general for that matter but I have a problem that only a Macro or piece of VBA code can resolve for me. I have to edit a large number of data entries in a spreadsheet, cell by cell.
So on to the question. Could you please show me an example or provide a complete macro for me to use to edit these cells?
The editing that I require is as follows:
I need to read each cell in the following range: B2 to Q383. A typical entry that needs to be examined and edited looks like this: 629.64\3.00\01:30
What needs to happen now is for everything to the left of the first "\" and everything to the right of the second "\" needs to be removed, including the "\", from each cell.
I've tried fiddling around with the LEFT and RIGHT commands and I can output the data that needs to be removed from the cells with something like this
=left(B11, Find("\", B11) - 1)
So what would be the delete command in a macro to target that data selection in that cell? Or how do I use a delete command with those parameters?
Thanks in advance for any advice or answers!
Not 100% sure what you're after - you say you want to remove the bits from the left and right, but the formula returns the bit on the left.
Anyway, here's 3 formula to do it:
Left: =TRIM(LEFT(B11,FIND("\",B11)-1))
Middle: =LEFT(MID(B11,FIND("\",B11)+1,LEN(B11)),FIND("\",MID(B11,FIND("\",B11)+1,LEN(B11)))-1)
Right: =MID(B11,FIND("\",SUBSTITUTE(B11,"\","~",1))+1,LEN(B11))
And three VBA functions to do it
(use these as you would formula - =leftbit(B11), or if you're looking for something other than backslashes - =leftbit(B11,"|") will find the I-bar as a divider. )
Public Function LeftBit(target As Range, Optional Divider As String = "\") As String
LeftBit = Trim(Left(target, InStr(target, Divider) - 1))
End Function
Public Function MiddleBit(target As Range, Optional Divider As String = "\") As String
Dim First As Long, Second As Long
First = InStr(target, Divider)
Second = InStr(First + 1, target, Divider)
MiddleBit = Mid(target, First + 1, Second - First - 1)
End Function
Public Function RightBit(target As Range, Optional Divider As String = "\") As String
RightBit = Right(target, Len(target) - InStrRev(target, Divider))
End Function

VBA PublishObjects. Add character formatting

I found the article about putting excel cells into an email using the RangetoHTML function in VBA. It works like a charm, but now I’m facing a Problem.
If there are Umlaut (e.g.: ü, ä, ö) in the cells the result in the email shows strange symbols (e.g.: ä, …).
I looked up the written temp.htm file. On the first view of this file, it seems the umlaute are correctly written, but after looking through the file with an hex editor i found that the written symbols are not correct.
The function which writes the file is: PublishObjects.Add
So I hope someone can help me with this.
Edit: Added a testfile. Word and Office is needed.
Select the table and run the procedure SendMail.
You will always have problems with vba and foreign chars and the web.
EDIT:
Because you can't separate the cell values from the html the function below will unfortunately not work in this situation. BUT:
if you Save a copy of the document with western European windows encoding it will work.
(See comments below).
To be able to do that you press "Save As" and there is a dropdown on the left side of the save button (Tools) which will give you a dialog where you can change the encoding.
The image has ben lifted from technet and always save web.. is not necessary.
EOF EDIT:
This is a function I have used, Unfortunately can't remember who I got it from, But its from the olden days of vba and classic asp
Put your email cell formula into this function and it should work because all the letters are html encoded. Its slow and makes a bad overhead. But it will work.
Function HtmlEncode(ByVal inText As String) As String
Dim i As Integer
Dim sEnc As Integer
Dim repl As String
HtmlEncode = inText
For i = Len(HtmlEncode) To 1 Step -1
sEnc = Asc(Mid$(HtmlEncode, i, 1))
Select Case sEnc
Case 32
repl = " "
Case 34
repl = """
Case 38
repl = "&"
Case 60
repl = "<"
Case 62
repl = ">"
Case 32 To 127
'Numbers
Case Else
repl = "&#" & CStr(sEnc) & ";" 'Encode it all
End Select
If Len(repl) Then
HtmlEncode = Left$(HtmlEncode, i - 1) & repl & Mid$(HtmlEncode, i + 1)
repl = ""
End If
Next
End Function

Resources