VBA to print to access tables - ms-access

I am building a library database and i have a working script to probe a web database using the ISBN number and return data about the book. I have successfully made the data print to the immediate window using debug.print and then the specific property of the object. I am now wanting to print the data retrieved straight in to the database.
here is my code for the ISBN search:
Option Compare Database
Dim BookTitle As String
Dim BookTitleLong As String
Dim BookAuthorsText As String
Dim BookPublisherText As String
Dim BookSummary As String
Dim BookNotes As String
Dim accessKey As String
Private Sub Class_Initialize()
'Your isbnDB access key'
accessKey = "xxxxxx" 'Working access key here
End Sub
Property Get Title() As String
Title = BookTitle
End Property
Property Get TitleLong() As String
TitleLong = BookTitleLong
End Property
Property Get AuthorsText() As String
AuthorsText = BookAuthorsText
End Property
Property Get PublisherText() As String
PublisherText = BookPublisherText
End Property
Property Get Summary() As String
Summary = BookSummary
End Property
Property Get Notes() As String
Notes = BookNotes
End Property
Public Function Lookup(ISBN As String) As Boolean
Lookup = False
Dim xmlhttp
Set xmlhttp = CreateObject("MSXML2.xmlhttp")
xmlhttp.Open "GET", "https://isbndb.com/api/books.xml?access_key=" & accessKey & "&results=texts&index1=isbn&value1=" & ISBN, False
xmlhttp.send
'Debug.Print "Response: " & xmlhttp.responseXML.XML'
Dim xmldoc
Set xmldoc = CreateObject("Microsoft.XMLDOM")
xmldoc.async = False
'Note: the ResponseXml property parses the server's response, responsetext doesn't
xmldoc.loadXML (xmlhttp.responseXML.XML)
If (xmldoc.selectSingleNode("//BookList").getAttribute("total_results") = 0) Then
MsgBox "Invalid ISBN or not in database"
Exit Function
End If
If (xmldoc.selectSingleNode("//BookList").getAttribute("total_results") > 1) Then
MsgBox "Caution, got more than one result!"
Exit Function
End If
BookTitle = xmldoc.selectSingleNode("//BookData/Title").Text
BookTitleLong = xmldoc.selectSingleNode("//BookData/TitleLong").Text
BookAuthorsText = xmldoc.selectSingleNode("//BookData/AuthorsText").Text
BookPublisherText = xmldoc.selectSingleNode("//BookData/PublisherText").Text
BookNotes = xmldoc.selectSingleNode("//BookData/Notes").Text
BookSummary = xmldoc.selectSingleNode("//BookData/Summary").Text
Lookup = True
End Function
and here is the code i have used to print to the immediate window
Public Function t()
Dim book
Set book = New ISBN
book.Lookup ("0007102968")
Debug.Print book.Title
Debug.Print book.PublisherText
Debug.Print book.AuthorsText
Debug.Print book.TitleLong
Debug.Print book.Summary
Debug.Print book.Notes
End Function
this is all based off this question asked a few years back:
ISBN -> bookdata Lookup to fill in a database
i would also like to be able to input the ISBN through a form if anyone can help with that :)

You can try the following approach.
First of all, create a user-defined data type to store the book data:
Public Type Book
ISBN As String
Title As String
TitleLong As String
AuthorsText As String
PublisherText As String
Summary As String
Notes As String
End Type
Then create an insert query and pass the book values as parameters. Let's name the query qryAdd.
PARAMETERS prmISBN Text (255),
prmTitle Text (255),
prmPublisherText Text (255),
prmAuthorsText Text (255),
prmTitleLong Text (255),
prmSummary LongText,
prmNotes LongText;
INSERT INTO T ( ISBN, Title, PublisherText, AuthorsText, TitleLong, Summary, Notes )
SELECT prmISBN AS ISBN,
prmTitle AS Title,
prmPublisherText AS PublisherText,
prmAuthorsText AS AuthorsText,
prmTitleLong AS TitleLong,
prmSummary AS Summary,
prmNotes AS Notes;
'Change T to the name of your table and update the field names.
Lastly, the function to call the insert query where we pass the book to be inserted.
Public Function InsertToDatabase(b As Book) As Boolean
With CurrentDb().QueryDefs("qryAdd")
.Parameters("[prmISBN]").Value = b.ISBN
.Parameters("[prmTitle]").Value = b.Title
.Parameters("[prmTitleLong]").Value = b.TitleLong
.Parameters("[prmPublisherText]").Value = b.PublisherText
.Parameters("[prmAuthorsText]").Value = b.AuthorsText
.Parameters("[prmSummary]").Value = b.Summary
.Parameters("[prmNotes]").Value = b.Notes
.Execute dbFailOnError
End With
'all good
InsertToDatabase = True
End Function
To test it:
Sub Test()
Dim b As Book
b.ISBN = "aaa"
b.Title = "bbb"
b.TitleLong = "ccc"
b.PublisherText = "ddd"
b.AuthorsText = "eee"
b.Summary = "fff"
b.Notes = "ggg"
If InsertToDatabase(b) Then MsgBox "Done!"
End Sub

Related

Visual Basic - How to use a variable from one function in another

I have checked Google, and the suggested answers here, but have had no luck unfortunately.
The last thing I need to do is have an email read the rateNbr variable into the email body, but it just comes up empty.
I tried to make Public Function FuncRateCheckFile read as Public Function FuncRateCheckFile(ByVal rateNbr As String), to try and enable it to be called outside the function, but this then breaks the function when it is called elsewhere. :(
Here is the code, with comments as to where I am referring:
Public Function FuncRateCheckFile()
Dim blnContinue As Boolean
Dim strLine As String
Dim strSearchFor, strSearchWrd, LineCount, objFSO, objTextFile, arrLines
Dim dteNow As Date
Dim newDate As String
'//==============================================================================================
'// DECLARED
Dim rateNbr As String
'//==============================================================================================
FuncRateCheckFile = False
blnContinue = True
If blnContinue Then
Const ForReading = 1
'Get todays date and reformat it
dteNow = DateValue(Now)
newDate = Format(dteNow, "dd/MM/yy")
strSearchWrd = newDate
'Read the whole file
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(m_RateCheckFile, ForReading)
LineCount = 0
Do Until objTextFile.AtEndOfStream
strLine = objTextFile.ReadLine()
If InStr(strLine, strSearchWrd) <> 0 Then
arrLines = Split(strLine, vbCrLf)
LineCount = LineCount + 1
End If
Loop
'Log a message to state how many lines have todays day, and if there are none, log an error
If LineCount <> 0 Then
'//==============================================================================================
'// "rateNbr" IS WHAT I AM TRYING TO GET TO PUT IN THE EMAIL
LogMessage "Rate file date is correct"
rateNbr = "Number of rates for " & newDate & " in the file recieved on " & newDate & " is " & LineCount
LogMessage rateNbr
EmailAdvice2
objTextFile.Close
'//==============================================================================================
Else
blnContinue = False
LogError "Failed to retrieve Current Rate date, please check rate file.."
EmailAdvice
objTextFile.Close
End If
End If
FuncRateCheckFile = blnContinue
LogMessage "Completed Check Rate file"
End Function
Private Function EmailAdvice2()
Dim strSMTPFrom As String
Dim strSMTPTo As String
Dim strSMTPRelay As String
Dim strTextBody As String
Dim strSubject As String
Dim oMessage As Object
'//==============================================================================================
'// DECLARED AGAIN
Dim rateNbr As String
'//==============================================================================================
Set oMessage = CreateObject("CDO.Message")
strSMTPFrom = "no-reply#work.com.au"
strSMTPTo = "me#work.com.au"
strSMTPRelay = "smtp.relay.com"
'//==============================================================================================
'// THIS MAKES THE TEXT BODY BLANK, BUT THE EMAIL STILL SENDS
strTextBody = rateNbr
'//==============================================================================================
strSubject = "Todays rates"
'strAttachment = "full UNC path of file"
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strSMTPRelay
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
oMessage.Configuration.Fields.Update
oMessage.Subject = strSubject
oMessage.From = strSMTPFrom
oMessage.To = strSMTPTo
oMessage.textbody = strTextBody
'oMessage.AddAttachment strAttachment
oMessage.Send
End Function
I am positive that it is blank because I have declared rateNbr under EmailAdvice2() and then not given it anything to fill the variable with. But I don't know how to make it call the variable under FuncRateCheckFile().
Thanks to all for any assistance.
As Plutonix stated, this is a scope issue.
Move the declaration of your 'rateNbr' variable out to class level, and remove the local declarations inside your functions:
Dim rateNbr As String ' <-- out at class level it will be accessible from both functions
Public Function FuncRateCheckFile()
...
' REMOVE both the decalarations of "rateNbr" that are INSIDE your functions
...
End Function
Private Function EmailAdvice2()
...
' REMOVE both the decalarations of "rateNbr" that are INSIDE your functions
...
End Function

Type mismatch when comparing two variants, why?

I have written a function that’s sole purpose is to loop through all forms in a continuous form, grab the names from an "Owner" field, and then create a collection out of them which only contains unique values (no repeated names).
The code below is my current code, I realize that this may seems to be a roundabout way to do what I want but some unforeseen issues prevent me from doing this the way I would like to. So while I realize the code isn't super effective (and is very rough coding) I want to finish this path if only for a learning experience. This line of code always gives me a type mismatch error message. I have used a break line to see what those variables are in the local window, they both contain a string which should be the same therefore should return true. I can't seem to find a way to make that comparison actually work.
ElseIf var = o Then
The code (heavy commenting to make sure I am clear):
Private Sub Command39_Click()
Dim intRecordCount As Integer
Dim rs As DAO.Recordset
Dim colNames As Collection
Set colNames = New Collection
Set rs = Me.RecordsetClone
intRecordCount = rs.RecordCount
DoCmd.GoToRecord , , acFirst
If intRecordCount > 0 Then
Dim thisCol As Collection
Set thisCol = New Collection
'For each record on the form
Do While Not rs.EOF
Dim str As String
Dim o As Variant
str = Me.txtOwners.Value & ""
'If the textbox isn't empty
If Len(str) > 0 Then
'Send the string containing names ("Bob, Cheryl, Jeff, Tim")
Set thisCol = SplitNames(str)
'Loop through all of the names found
For Each o In thisCol
Dim var As Variant
Dim blnFound As Boolean
'Loop through all names in the main collection
For Each var In colNames
'If the collection is empty simply add the first name
If colNames.Count = 0 Then
blnFound = False
'If the collection has items check each one to see if the name is already in the collection
'This line is where the problem lies, I can't find anyway to compare var to o
ElseIf var = o Then
blnFound = True
End If
Next var
'If the name was not found in the collection add it
If Not blnFound Then
colNames.Add (o)
End If
Next o
End If
'Go to the next record in the continuous
DoCmd.GoToRecord , , acNext
rs.MoveNext
Loop
End If
End Sub
'Accepts the name of the owners to be split
Public Function SplitNames(strNames As String) As Collection
Dim colNames As Collection
Dim strThisName As String
Set colNames = New Collection
'Replaces ("Bob, Cheryl, Jeff, Tim") with ("Bob Cheryl Jeff Tim")
'I realize this isn't really needed simply my OCD requires I do
strNames = Trim(Replace(strNames, ", ", " "))
'Create the collection of names
colNames.Add (Split(strNames, " "))
'Send back the collection
Set SplitNames = colNames
End Function
Update - For some reason I need to access the var string propery by using var(0) so it seems like somehow var became its own array?
Here's an example of modifying your SplitNames function to a Dictionary object.
WHile there is an Exists method which you may make use of elsehwere in your code, you need not use that to ensure uniqueness. Merely referring to a Key will create it, so you can create a new key (or overwrite it if it exists) using the same method:
dict(key) = value
Note that this overwrites the value portion of the Key/Value pair. But since your SplitNames function is merely building the "list" of unique names, I don't think that will be an issue. For the sake of example, I simply assign nullstring to each value.
I added an optional parameter to this function to allow you to return either a Dictionary of unique names, or a Collection (converted from the Dictionary). Untested, but I think it should work. Let me know if you have any trouble with it.
Public Function SplitNames(strNames As String, Optional returnCollection as Boolean=False) As Object
'returns a Dictionary of unique names, _
' or a Collection of unique names if optional returnCollection=True
Dim dictNames as Object
Dim strThisName As Variant
Dim coll as Collection
Set dictNames = CreateObject("Scripting.Dictionary")
'Replaces ("Bob, Cheryl, Jeff, Tim") with ("Bob Cheryl Jeff Tim")
'I realize this isn't really needed simply my OCD requires I do
strNames = Trim(Replace(strNames, ", ", " "))
'Create the collection of names
For Each strThisName in Split(strNames, " ")
dictNames(strThisName) = ""
Next
If Not returnCollection Then
Set SplitNames = dictNames
Else
Set coll = New Collection
For each strThisName in dictNames.Keys()
coll.Add strThisName
Next
Set SplitNames = coll
End If
End Function
So I think you can reduce your procedure like so:
Private Sub Command39_Click()
Dim intRecordCount As Integer
Dim rs As DAO.Recordset
Dim dictNames As Object
Dim collNames as Collection
Dim str As String
Dim o As Variant
Set rs = Me.RecordsetClone
intRecordCount = rs.RecordCount
DoCmd.GoToRecord , , acFirst
rs.MoveFirst
If intRecordCount > 0 Then
'For each record on the form
Do While Not rs.EOF
str = Me.Controls("Text27").Value & ""
'If the textbox isn't empty
If Len(str) > 0 Then
'Send the string containing names ("Bob, Cheryl, Jeff, Tim")
Set dictNames = SplitNames(str)
'Alternatively, if you want to work with the Collection instead:
Set collNames = SplitNames(str, True)
End If
Loop
End If
End Sub
The following is the updated code that works for what I need it to do. I was adding a string array (being created by the Split() function) which was what I was adding instead of the string value itself.
Private Sub Command39_Click()
Dim intRecordCount As Integer
Dim rs As DAO.Recordset
Dim dictNames As New Collection
Set rs = Me.RecordsetClone
intRecordCount = rs.RecordCount
DoCmd.GoToRecord , , acFirst
rs.MoveFirst
If intRecordCount > 0 Then
Dim dictTheseNames As New Collection
'For each record on the form
Do While Not rs.EOF
Dim str As String
Dim o As Variant
str = Me.Controls("Text27").Value & ""
'If the textbox isn't empty
If Len(str) > 0 Then
'Send the string containing names ("Bob, Cheryl, Jeff, Tim")
Set dictTheseNames = SplitNames(str)
'Loop through all of the names found
For Each o In dictTheseNames
Dim var As Variant
Dim blnFound As Boolean
blnFound = False
'Loop through all names in the main collection
For Each var In dictNames
'If the collection is empty simply add the first name
If dictNames.Count = 0 Then
dictNames.Add (o)
'If the collection has items check each one to see if the name is already in the collection
'This line is where the problem lies, I can't find anyway to compare var to o
ElseIf o = var Then
blnFound = True
End If
Next var
'If the name was not found in the collection add it
If Not blnFound Then
dictNames.Add (o)
End If
Next o
End If
'Go to the next record in the continuous
rs.MoveNext
If (rs.RecordCount - rs.AbsolutePosition) > 2 Then
DoCmd.GoToRecord , , acNext
End If
Loop
End If
End Sub
'Accepts the name of the owners to be split
Public Function SplitNames(strNames As String) As Collection
Dim dictNames As New Collection
Dim strThisName As String
Dim strArray() As String
Set dictNames = New Collection
'Replaces ("Bob, Cheryl, Jeff, Tim") with ("Bob Cheryl Jeff Tim")
'I realize this isn't really needed simply my OCD requires I do
strNames = Trim(Replace(strNames, ", ", " "))
'Create the array of names
strArray = Split(strNames, " ")
Dim o As Variant
For Each o In strArray
dictNames.Add (o)
Next o
'Send back the collection
Set SplitNames = dictNames
End Function

MS ACCESS VBA module Auto number format

I have a Repoerteq table with a REQ_NUM as ID and another column named "REQ_department".
REQ_department have defult values such as ""Finance".
I want to make VBA looks at the department and then set a prefix formate for REQ_NUM
example is department is finance then it would make id as "FIN 000"
the following code is what i manage fo far but it still not working
Option Compare Database
Function GetData() As String
Dim db As Database
Dim Rrs As DAO.Recordset
Dim RSQL As String
Dim RepData As String
Dim RepDep As String
'TO open connection to current Access DB
Set db = CurrentDb()
'TO create SQL statement and retrieve value from ReportReq table
RSQL = "select * from ReportReq"
Set Rrs = db.OpenRecordset(RSQL)
'Retrieve value if data is found
If Rrs.EOF = False Then
RepData = Rrs("REQ_NUM")
RepDep = Rrs("Req_department")
Else
RepData = "Not found"
RepDep = "Not found"
End If
Lrs.Close
Set Lrs = Nothing
GetData = RepData
If ReqDep = "finance" Then
Range("REQ_NUM") = Format$("FIN", REQ_NUM)
End If
End Function
You'll have to change your call to the Format() function which tries to format a number or date according to the format string. In addition, you're using an undefined variable REQ_NUM.
If ReqDep = "finance" Then
Range("REQ_NUM") = "FIN " & Format$("000", CLng(RepData))
' ^^^^^^ ^^^^^^^^^^^^^^^^^^^^
End If

How can I get reference to a variable by using a string, in VBA?

I have a variable strFunction, then I have another string strName = "strFunction" , what I want to know is how can I get the value of strFunction by using strName.
For example, something like getValue(strName) gives me the value of strFunction. Is it possible in Access VBA?
Thanks!
EDIT:
I have a strFunction string, it's a const string.
In my code I want to use Len("strFunction") to test the length of it, but what i got is the length "strFunction". So I need a get-value-out-of-variable-name function. I have tried Eval(), but it cannot do this, even I write a get_strFunction(), eval("get_strFunction()") gives me error, telling me it cannot find it.
Private Const strFunction as String = "FilterByType_1"
Private Function get_strFunction()
get_strFunction = strFunction
End Function
"I have a variable strFunction, then I have another string strName = "strFunction" , what I want to know is how can I get the value of strFunction by using strName."
Instead of a variable, strFunction could be the key for an item in a VBA collection.
Public Sub darkjh()
Dim strName As String
Dim col As Collection
Set col = New Collection
col.Add "FilterByType_1", "strFunction"
strName = "strFunction"
Debug.Print col(strName)
Set col = Nothing
End Sub
Edit: Instead of a VBA collection, you could use a Scripting.Dictionary.
Dim strName As String
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict.Add "strFunction", "FilterByType_1"
strName = "strFunction"
Debug.Print dict(strName)
Set dict = Nothing
Option Compare Database
Dim a As String
Dim b As String
Public Sub test()
a = "b"
b = "test-string"
Debug.Print Eval("get" & a & "()")
End Sub
Public Function getB() As String
getB = b
End Function
Output
>>test
test-string
eval(a) did not work, so I had to write a "getter" for the variable and eval that function: eval("get" & a & "()").

Return multiple values from a function, sub or type?

So I was wondering, how can I return multiple values from a function, sub or type in VBA?
I've got this main sub which is supposed to collect data from several functions, but a function can only return one value it seems. So how can I return multiple ones to a sub?
You might want want to rethink the structure of you application, if you really, really want one method to return multiple values.
Either break things apart, so distinct methods return distinct values, or figure out a logical grouping and build an object to hold that data that can in turn be returned.
' this is the VB6/VBA equivalent of a struct
' data, no methods
Private Type settings
root As String
path As String
name_first As String
name_last As String
overwrite_prompt As Boolean
End Type
Public Sub Main()
Dim mySettings As settings
mySettings = getSettings()
End Sub
' if you want this to be public, you're better off with a class instead of a User-Defined-Type (UDT)
Private Function getSettings() As settings
Dim sets As settings
With sets ' retrieve values here
.root = "foo"
.path = "bar"
.name_first = "Don"
.name_last = "Knuth"
.overwrite_prompt = False
End With
' return a single struct, vb6/vba-style
getSettings = sets
End Function
You could try returning a VBA Collection.
As long as you dealing with pair values, like "Version=1.31", you could store the identifier as a key ("Version") and the actual value (1.31) as the item itself.
Dim c As New Collection
Dim item as Variant
Dim key as String
key = "Version"
item = 1.31
c.Add item, key
'Then return c
Accessing the values after that it's a breeze:
c.Item("Version") 'Returns 1.31
or
c("Version") '.Item is the default member
Does it make sense?
Ideas :
Use pass by reference (ByRef)
Build a User Defined Type to hold the stuff you want to return, and return that.
Similar to 2 - build a class to represent the information returned, and return objects of that class...
You can also use a variant array as the return result to return a sequence of arbitrary values:
Function f(i As Integer, s As String) As Variant()
f = Array(i + 1, "ate my " + s, Array(1#, 2#, 3#))
End Function
Sub test()
result = f(2, "hat")
i1 = result(0)
s1 = result(1)
a1 = result(2)
End Sub
Ugly and bug prone because your caller needs to know what's being returned to use the result, but occasionally useful nonetheless.
A function returns one value, but it can "output" any number of values. A sample code:
Function Test (ByVal Input1 As Integer, ByVal Input2 As Integer, _
ByRef Output1 As Integer, ByRef Output2 As Integer) As Integer
Output1 = Input1 + Input2
Output2 = Input1 - Input2
Test = Output1 + Output2
End Function
Sub Test2()
Dim Ret As Integer, Input1 As Integer, Input2 As Integer, _
Output1 As integer, Output2 As Integer
Input1 = 1
Input2 = 2
Ret = Test(Input1, Input2, Output1, Output2)
Sheet1.Range("A1") = Ret ' 2
Sheet1.Range("A2") = Output1 ' 3
Sheet1.Range("A3") = Output2 '-1
End Sub
you can return 2 or more values to a function in VBA or any other visual basic stuff but you need to use the pointer method called Byref. See my example below. I will make a function to add and subtract 2 values say 5,6
sub Macro1
' now you call the function this way
dim o1 as integer, o2 as integer
AddSubtract 5, 6, o1, o2
msgbox o2
msgbox o1
end sub
function AddSubtract(a as integer, b as integer, ByRef sum as integer, ByRef dif as integer)
sum = a + b
dif = b - 1
end function
Not elegant, but if you don't use your method overlappingly you can also use global variables, defined by the Public statement at the beginning of your code, before the Subs.
You have to be cautious though, once you change a public value, it will be held throughout your code in all Subs and Functions.
I always approach returning more than one result from a function by always returning an ArrayList. By using an ArrayList I can return only one item, consisting of many multiple values, mixing between Strings and Integers.
Once I have the ArrayList returned in my main sub, I simply use ArrayList.Item(i).ToString where i is the index of the value I want to return from the ArrayList
An example:
Public Function Set_Database_Path()
Dim Result As ArrayList = New ArrayList
Dim fd As OpenFileDialog = New OpenFileDialog()
fd.Title = "Open File Dialog"
fd.InitialDirectory = "C:\"
fd.RestoreDirectory = True
fd.Filter = "All files (*.*)|*.*|All files (*.*)|*.*"
fd.FilterIndex = 2
fd.Multiselect = False
If fd.ShowDialog() = DialogResult.OK Then
Dim Database_Location = Path.GetFullPath(fd.FileName)
Dim Database_Connection_Var = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=""" & Database_Location & """"
Result.Add(Database_Connection_Var)
Result.Add(Database_Location)
Return (Result)
Else
Return (Nothing)
End If
End Function
And then call the Function like this:
Private Sub Main_Load()
Dim PathArray As ArrayList
PathArray = Set_Database_Path()
My.Settings.Database_Connection_String = PathArray.Item(0).ToString
My.Settings.FilePath = PathArray.Item(1).ToString
My.Settings.Save()
End Sub
you could connect all the data you need from the file to a single string, and in the excel sheet seperate it with text to column.
here is an example i did for same issue, enjoy:
Sub CP()
Dim ToolFile As String
Cells(3, 2).Select
For i = 0 To 5
r = ActiveCell.Row
ToolFile = Cells(r, 7).Value
On Error Resume Next
ActiveCell.Value = CP_getdatta(ToolFile)
'seperate data by "-"
Selection.TextToColumns Destination:=Range("C3"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar _
:="-", FieldInfo:=Array(Array(1, 1), Array(2, 1)), TrailingMinusNumbers:=True
Cells(r + 1, 2).Select
Next
End Sub
Function CP_getdatta(ToolFile As String) As String
Workbooks.Open Filename:=ToolFile, UpdateLinks:=False, ReadOnly:=True
Range("A56000").Select
Selection.End(xlUp).Select
x = CStr(ActiveCell.Value)
ActiveCell.Offset(0, 20).Select
Selection.End(xlToLeft).Select
While IsNumeric(ActiveCell.Value) = False
ActiveCell.Offset(0, -1).Select
Wend
' combine data to 1 string
CP_getdatta = CStr(x & "-" & ActiveCell.Value)
ActiveWindow.Close False
End Function