The Adobe process doesn't close after the code is finished - excel

I'm adding bookmarks after I merged pdf files. The script does the job, but because of one variant, the Adobe-process doesn’t close after.
The Variants name is "BMA". If removed, then the process will close as designed.
I made a script closing all process, but I want a more solid solution. Please help.
Option Explicit
Sub testrun()
Dim aInfo(6) As String
'True = bookmark
'False = child bookmark
aInfo(0) = "True,Index,0"
aInfo(1) = "True,Document_1,1"
aInfo(2) = "False,Attatchment_1,2"
aInfo(3) = "True,Document_2,3"
aInfo(4) = "False,Attatchment_1,4"
aInfo(5) = "False,Attatchment_2,5"
Call NewFixPDF("C:\Temp\Test.pdf", aInfo)
End Sub
Private Sub NewFixPDF(sFile As String, aInfo() As String)
Dim AcroApp As Acrobat.CAcroApp
Dim PDDoc As Acrobat.CAcroPDDoc
Dim jso As Object
Dim BMR As Object, oBMR As Object, oBMA As Object
Dim BMA As Variant
Set AcroApp = CreateObject("AcroExch.App")
Set PDDoc = CreateObject("AcroExch.PDDoc")
Dim a As Integer, b As Integer, i As Integer
Dim aBookmark() As String
Dim bHead As Boolean
Dim sName As String
Dim iPage As Integer
If PDDoc.Open(sFile) = False Then
MsgBox "Can't open file", vbCritical
GoTo Exit_Sub
End If
Set jso = PDDoc.GetJSObject
jso.bookmarkRoot.Remove
Set BMR = jso.bookmarkRoot
Set oBMR = jso.bookmarkRoot
For i = 0 To UBound(aInfo) - 1
aBookmark = Split(aInfo(i), ",")
bHead = aBookmark(0)
sName = aBookmark(1)
iPage = aBookmark(2)
If bHead Then
If InStr(sName, "-") > 0 Then sName = Mid(sName, 3 + Len(sName) - InStr(StrReverse(sName), "-"))
BMR.createchild sName, "this.pageNum = " & iPage, a
BMA = BMR.Children
Set oBMA = BMA(a)
a = a + 1
b = 0
Else
oBMA.createchild sName, "this.pageNum = " & iPage, b
b = b + 1
End If
Next i
If PDDoc.Save(PDSaveFull, sFile) = False Then
MsgBox "Can't add bookmarks", vbCritical
End If
Exit_Sub:
Set BMR = Nothing
Set oBMR = Nothing
Set oBMA = Nothing
PDDoc.Close
AcroApp.Exit
Set AcroApp = Nothing
Set PDDoc = Nothing
Debug.Print "Done"
End Sub

Related

Opening Word Document in VBA Results in Empty Variable

I am trying to loop through a folder and open each word document one at a time in VBA. I had the code working, and then I added two more files to the folder. Now it won't open my first file (which I had opened previously. My code is as follows:
Sub readEmailsV2()
Dim oFSO As Object, oFolder As Object, oFile As Object
Dim i As Integer
Dim j As Integer
Dim pN As Integer
Dim sFileSmall As String, sFileYear As String, sFilePath As String
Dim wapp As Word.Application
Dim wdoc As Word.Document
Dim tabDest As Worksheet
Dim splitVals As Variant
Dim contentsVar As String
Dim jContent As String
Dim pageCount As Integer
Dim fpOpen As Variant
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' USER INPUT
sFileSmall = "C:\Users\rstrott\OneDrive - Research Triangle Institute\Desktop\VBApractice\Docket Index\filesToRead\"
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Get variable with filenames from folder (Only contains word docs)
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.getfolder(sFileSmall)
Set tabDest = ThisWorkbook.Sheets("FileContents")
Set wapp = GetObject(, "Word.Application")
If wapp Is Nothing Then
Set wapp = CreateObject("Word.Application")
End If
tabDest.Cells.Clear
tabDest.Range("a1:a1") = "File Title"
tabDest.Range("b1:b1") = "From:"
tabDest.Range("c1:c1") = "To:"
tabDest.Range("d1:d1") = "cc:"
tabDest.Range("e1:e1") = "Date Sent:"
tabDest.Range("f1:f1") = "Subject:"
tabDest.Range("g1:g1") = "Body:"
tabDest.Range("h1:h1") = "Page Count:"
i = 2
For Each oFile In oFolder.Files
' Assign variables
sFilePath = sFileSmall & oFile.Name
wapp.Visible = True
fpOpen = oFile.Path
Set wdoc = wapp.Documents.Open(sFilePath) ' <---- ERROR HERE: Output is 'Nothing'
pN = ActiveDocument.Paragraphs.Count
pageCount = ActiveDocument.ActiveWindow.ActivePane.Pages.Count
' Put paragraph contents in cells
tabDest.Cells(i, 1) = oFile.Name
tabDest.Cells(i, 2) = wdoc.Paragraphs(2)
tabDest.Cells(i, 3) = wdoc.Paragraphs(8)
tabDest.Cells(i, 4) = wdoc.Paragraphs(11)
tabDest.Cells(i, 5) = wdoc.Paragraphs(5)
tabDest.Cells(i, 6) = wdoc.Paragraphs(14)
Dim item As Variant
For j = 15 To pN
jContent = wdoc.Paragraphs(j).Range.Text
If j = 15 And Len(jContent) > 2 Then
contentsVar = wdoc.Paragraphs(j).Range.Text
ElseIf Len(jContent) > 2 Then
contentsVar = contentsVar & Chr(10) & wdoc.Paragraphs(j).Range.Text
End If
Next j
tabDest.Cells(i, 7) = contentsVar
tabDest.Cells(i, 8) = pageCount
' Close Word Doc
wdoc.Close _
SaveChanges:=wdDoNotSaveChanges
i = i + 1
Next oFile
End Sub
I've tried lots of different things to get it to work again, and I ran out of ideas. Any help would be greatly appreciated.

Only apply VBA code to e-mails containing "string" in the subject

I am using a code that works great - the purpose is to send info from Outlook to Excel so I can filter it and automatize the work.
The problem is: the VBA code is executing for all e-mails received and I only want to execute it onto e-mails with subject starting with "EK".
I already tried using InStr function as below, but it doesn't work:
If InStr(xMailItem.Subject, "EK") = 0 Then
Exit Sub
End If
Where should I put this line of code?
Private Sub GMailItems_ItemAdd(ByVal Item As Object)
Dim xMailItem As Outlook.MailItem
Dim xExcelFile As String
Dim xExcelApp As Excel.Application
Dim xWb As Excel.Workbook
Dim xWs As Excel.Worksheet
Dim xNextEmptyRow As Integer
Dim linhas As Variant, i As Integer
Dim linhaInicial As Long
Dim numeroCaracteresAssunto As Integer
Dim assuntoEmail As String
Dim k As Integer
On Error Resume Next
If (Item.Class <> olMail) Then Exit Sub
Set xMailItem = Item
xExcelFile = "EXCELFILEPATH.xlsx"
If IsWorkBookOpen(xExcelFile) = True Then
Set xExcelApp = GetObject(, "Excel.Application")
Set xWb = GetObject(xExcelFile)
If Not xWb Is Nothing Then xWb.Close True
Else
Set xExcelApp = New Excel.Application
End If
Set xWb = xExcelApp.Workbooks.Open(xExcelFile)
Set xWs = Sheets.Add
numeroCaracteresAssunto = Len(xMailItem.Subject)
assuntoEmail = Right(xMailItem.Subject, numeroCaracteresAssunto - 16)
xWs.Name = UCase(assuntoEmail)
xNextEmptyRow = xWs.Range("B" & xWs.Rows.Count).End(xlUp).Row + 1
linhaInicial = 1
With xWs
linhas = Split(xMailItem.Body, vbNewLine)
For i = 0 To UBound(linhas)
Cells(linhaInicial + i, 1).Value = linhas(i)
linhaInicial = linhaInicial + 1
Next
For k = 1 To i
xWs.Range("B" & k).FormulaLocal = "=SEERRO(ÍNDICE($A$1:$A$999;MENOR(SE(ÉNÚM(LOCALIZAR(""PC"";$A$1:$A$999));CORRESP(LIN($A$1:$A$999);LIN($A$1:$A$999)));" & k & "));"""")"
xWs.Range("B" & k).FormulaArray = xWs.Range("B" & k).Formula
Next k
End With
End Sub
Instr is not case sensitive.
If InStr(UCase(xMailItem.Subject), UCase("EK")) = 0 Then
Either UCase or LCase.
On both parts, or you may run into an "eK" typo.

VB.NET - Working with Excel and cannot release files once complete

I created an app that does the following:
Opens an excel spreadsheet and show a hidden sheet
Copy the data in this sheet to a temporary spreadsheet
Run some error checks on the data that's been pasted
Create a unique code in the first column based on customer no. date & time
Save the spreadsheet as a new file
Clear up to be ready for the next spreadsheet
The problem I am having is at step 6 of clearing up and releasing any excel objects in memory that can hold up moving to the next spreadsheet and so on.
The current issue I have is that an Excel object remains open and locks the tempfile.xlsx that is created which will then randomly generates the error "The file 'C:\Temp\CustOrders\Input\TempFile.xlsx' already exists." I say randomly because I can run 10 or more files through it without an issue. I could run them all again and it will produce the error after the 1st, 2nd, 3rd or later file. I cannot blame any one file for causing this.
How do I effectively close out all Excel objects ready for the next file to be processed? I have so far tried different ways to do this including trying to kill the process but this seems like a dirty sledgehammer approach.
Here's the code:
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
Imports System.Runtime.InteropServices
Imports System.IO
Public Class Form1
Dim xlApp As Excel.Application
Dim xlNewApp As Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet
Dim range As Excel.Range
Dim rCnt As Integer
Dim cCnt As Integer
Dim Obj As Object
Dim TempFile() As String
Dim TempFiledir As String
Dim filename As String
Dim xlNewWorkBook As Excel.Workbook
Dim xlNewWorkSheet As Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
Dim Cust As Object
Dim pfile As String
Dim NoProcessed As Integer = 0
Dim NoFailed As Integer = 0
Dim filecount As Integer = 0
Dim fileremaining As Integer = 0
Dim custFailed As Integer = 0
Dim files() As String = Directory.GetFiles("C:\Temp\CustOrders\Uploaded")
Dim di As New DirectoryInfo("C:\Temp\CustOrders\Uploaded")
Private Sub releaseObject(ByVal obj As Object)
Try
Marshal.ReleaseComObject(obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
lblProcessingFile.Visible = False
CountFiles()
lblFileCount.Text = "Files to be processed: " & filecount
End Sub
Function CountFiles()
Dim files() As String = Directory.GetFiles("C:\Temp\CustOrders\Uploaded")
Dim di As New DirectoryInfo("C:\Temp\CustOrders\Uploaded")
If files.Count > 0 Then
filecount = di.GetFiles("*.xlsx").Count()
Else
filecount = 0
lblFileCount.Text = "Files to be processed: " & filecount
End If
End Function
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles BTN_gencsv.Click
TempFiledir = ("C:\Temp\CustOrders\Input\TempFile.xlsx")
If My.Computer.FileSystem.FileExists(TempFiledir) Then
My.Computer.FileSystem.DeleteFile(TempFiledir)
End If
GetFiles()
End Sub
Sub GetFiles()
'1. Look in the UPLOADED folder for new files
Dim files() As String = Directory.GetFiles("C:\Temp\CustOrders\Uploaded")
Dim di As New DirectoryInfo("C:\Temp\CustOrders\Uploaded")
If files.Count > 0 Then
Dim arrayfi As FileInfo() = di.GetFiles("*.xlsx")
Dim fi As FileInfo
For Each fi In arrayfi
filename = fi.Name
Start(filename)
Next
Else
MsgBox("No files available in directory")
End If
End Sub
Sub Start(filename)
With BTN_gencsv
.BackColor = Color.Red
.ForeColor = Color.White
.Text = "Please wait..."
End With
'2. Get the file that has been uploaded by the customer, copy and rename as TempFile
lblProcessingFile.Visible = True
lblProcessingFile.Text = "Processing file: " & filename
IO.File.Copy("C:\Temp\CustOrders\Uploaded\" & filename, _
"C:\Temp\CustOrders\Input\TempFile.xlsx")
xlApp = New Excel.Application
xlNewApp = New Excel.Application
xlWorkBook = xlApp.Workbooks.Open("C:\Temp\CustOrders\Input\TempFile.xlsx")
xlWorkSheet = xlWorkBook.Worksheets(1)
xlWorkSheet = xlWorkBook.Worksheets("CSV")
xlWorkSheet.Visible = XlSheetVisibility.xlSheetVisible
xlWorkSheet.Unprotect("opencsv")
'3. Copy rows from the CSV worksheet including headers
xlWorkSheet.Range("A1:H100").Copy()
'4. Create new Excel workbook and worksheet so it can have have all rows pasted in
' Then perform all prep work
xlNewWorkBook = xlNewApp.Workbooks.Add(misValue)
xlNewWorkSheet = xlNewWorkBook.Worksheets(1)
xlNewWorkSheet.Select()
' Paste the rows into the new worksheet
On Error Resume Next
xlNewWorkSheet.PasteSpecial(Excel.XlPasteType.xlPasteValues)
xlApp.CutCopyMode = False
' Get current date/time
Dim dt As DateTime = DateTime.Now
Dim dt2 As String = dt
dt2 = dt2.Replace("/", "").Replace(" ", "_").Replace(":", "")
' Select customer number from worksheet
Dim xRng As Excel.Range = CType(xlNewWorkSheet.Cells(2, 5), Excel.Range)
Cust = xRng.Value().ToString()
' If the customer is not found in the spreadsheet lookup it generates "-2146826246" as a value
' This saves the cell as "Not found" to make it look friendly
If Cust.Equals("-2146826246") Then
custFailed += 1
Cust = "Cust_Not_Found_" & custFailed
failedfiles()
Else
CustNo()
End If
releaseObject(xRng)
' This now passes to two error checking subs
End Sub
Sub completeform()
'5. Generate a unique value for Netsuite based on the customer number and current date time
Dim Row As Range
Dim Index As Long
Dim Count As Long
For Index = xlNewWorkSheet.UsedRange.Rows.Count To 1 Step -1
Row = xlNewWorkSheet.UsedRange.Rows(Index)
Count = 0
On Error Resume Next
Count = Row.SpecialCells(XlCellType.xlCellTypeBlanks).Count
If Count = Row.Cells.Count Then Row.Delete(Excel.XlDirection.xlUp)
Next
Dim dt As DateTime = DateTime.Now
Dim dt2 As String = dt
dt2 = dt2.Replace("/", "").Replace(" ", "_").Replace(":", "")
pfile = (Cust + "_" + dt2)
Dim rw As Integer = 1
Do Until xlNewWorkSheet.Cells(rw, 1).Value Is Nothing
rw += 1
Loop
Dim last As String = rw - 1
With xlNewWorkSheet.Range("A1:A100")
.Range(.Cells(2, 1), .Cells(last, 1)).Value = (Cust + "_" + dt2)
End With
'6. Save the workbook with a unique name based on customer number and date/time
xlWorkBook.Saved = True
xlNewWorkBook.SaveAs("C:\Temp\CustOrders\Output\Test_" + pfile + ".csv", Excel.XlFileFormat.xlCSV, misValue, misValue, misValue, misValue, _
Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue)
'7. Close and release all Excel worksheets and workbooks so they dont remain in memory
xlNewWorkBook.Close(True, misValue, misValue)
xlWorkBook.Saved = True
xlNewWorkBook.Saved = True
releaseObject(xlNewWorkSheet)
releaseObject(xlNewWorkBook)
releaseObject(xlNewApp)
xlWorkBook.Close(False)
xlApp.Quit()
releaseObject(range)
releaseObject(xlWorkSheet)
releaseObject(xlWorkBook)
releaseObject(xlApp)
xlNewApp.Quit()
System.Threading.Thread.Sleep(2000)
'8. Move the processed workbook to the Processed folder ready for a new workbook
IO.File.Move("C:\Temp\CustOrders\Input\TempFile.xlsx", _
"C:\Temp\CustOrders\Processed\Processedfile_" + pfile + ".xlsx")
'9. Move the spreadsheet from Uploaded to OldUploaded ready for a new file
IO.File.Move("C:\Temp\CustOrders\Uploaded\" + filename, _
"C:\Temp\CustOrders\OldUploaded\Uploaded_" + filename)
NoProcessed += 1
lblProcessedCount.Text = "No. Processed..." & NoProcessed
CountFiles()
lblFileCount.Text = "Files to be processed: " & filecount
With BTN_gencsv
.BackColor = SystemColors.Control
.ForeColor = SystemColors.ControlText
.Text = "Generate CSV"
End With
lblProcessingFile.Visible = False
End Sub
Sub CustNo()
Dim c As Range
With xlNewWorkSheet.Range("A1:A100")
c = .Find("#N/A", LookIn:=XlFindLookIn.xlValues)
If Not c Is Nothing Then
custFailed += 1
Cust = "Cust_Not_Found_" & custFailed
MsgBox(Cust)
failedfiles()
Else
quantityBlanks()
End If
End With
End Sub
Sub quantityBlanks()
Dim rw As Integer = 1
Do Until xlNewWorkSheet.Cells(rw, 1).Value Is Nothing
rw += 1
Loop
Dim last As String = rw - 1
Dim rng As Excel.Range
Dim TotalBlanks As Long
TotalBlanks = 0
rng = xlNewWorkSheet.Range(xlNewWorkSheet.Cells(2, 8), xlNewWorkSheet.Cells(last, 8))
On Error Resume Next
TotalBlanks = rng.SpecialCells(XlCellType.xlCellTypeBlanks).Count
If TotalBlanks > 0 Then
Cust = "Quantity_error_"
failedfiles()
Else
referrors()
End If
rng = Nothing
End Sub
Sub referrors()
Dim c As Range
With xlNewWorkSheet.Range("A1:A100")
c = .Find("#REF!", LookIn:=XlFindLookIn.xlValues)
If Not c Is Nothing Then
Cust = "~REF!_errors_"
failedfiles()
Else
completeform()
End If
End With
End Sub
Sub failedfiles()
Dim dt As DateTime = DateTime.Now
Dim dt2 As String = dt
dt2 = dt2.Replace("/", "").Replace(" ", "_").Replace(":", "")
pfile = (Cust + "_" + dt2)
xlWorkBook.Close(False)
xlNewWorkBook.Close(False)
xlNewApp.Quit()
xlApp.Quit()
releaseObject(xlApp)
releaseObject(xlWorkBook)
releaseObject(xlWorkSheet)
releaseObject(xlNewApp)
releaseObject(xlNewWorkBook)
releaseObject(xlNewWorkSheet)
'IO.File.Delete("C:\Temp\CustOrders\Input\Newfile.xlsx")
IO.File.Move("C:\Temp\CustOrders\Input\TempFile.xlsx", _
"C:\Temp\CustOrders\Processed\ProcessedFailedfile_" + pfile + ".xlsx")
IO.File.Move("C:\Temp\CustOrders\Uploaded\" + filename, _
"C:\Temp\CustOrders\Failed\FailedFile_" + pfile + ".xlsx")
With BTN_gencsv
.BackColor = SystemColors.Control
.ForeColor = SystemColors.ControlText
.Text = "Generate CSV"
End With
NoFailed += 1
lblFailed.ForeColor = Color.Red
lblFailed.Text = "No. Failed..." & NoFailed
CountFiles()
lblFileCount.Text = "Files to be processed: " & filecount
lblProcessingFile.Visible = False
End Sub
Private Sub PictureBox1_Click(sender As System.Object, e As System.EventArgs) Handles PictureBox1.Click
CountFiles()
lblFileCount.Text = "Files to be processed: " & filecount
End Sub
End Class

Closing an Excel Application using Outlook VBA after using an Excel function

I am working on a sort of "BOT" for Outlook (using Outlook VBA), in which I receive info by mail, split the mail body, paste it on Excel and execute Excel macros.
After adding the part where I call the Excel macro, I get
'1004 - application-defined or object-defined error'
if I'm running this for the second + time.
xlApp.Application.Run "AINT.Cali_B_Click"
Even though I'm setting my Excel variables to nothing and using .close and .quit, Excel is still running.
How can I end the application reference that is keeping Excel open?
Here's my full code:
Private Sub inboxItems_ItemAdd(ByVal Item As Object)
On Error GoTo ErrorHandler
Dim Msg As Outlook.MailItem
Dim MessageInfo
Dim Result
Dim splitter() As String
Dim splitter2() As String
Dim loopH As String
Dim str As Variant
Dim LoopCali As Integer
Dim i, j As Integer
Dim xlApp As Object
Dim sourceWB As Object
Dim Header, QuoteSTG, AINT, Treinamento As Object
Dim strFile, file_name As String
Dim shellcom As String
i = 1
If TypeName(Item) = "MailItem" Then
If InStr(Item.Subject, "BOT") > 0 Then
splitter = Split(Item.Body, vbCrLf)
Set xlApp = CreateObject("Excel.Application")
strFile = "C:\Users\e1257539\Desktop\SMOBOT\SMO_TOOL_BOT.xlsm"
With xlApp
.Visible = False
.EnableEvents = False
.DisplayAlerts = False
End With
Set sourceWB = Workbooks.Open(strFile)
sourceWB.Activate
Set Header = sourceWB.Sheets(4)
Set QuoteSTG = sourceWB.Sheets(13)
Set AINT = sourceWB.Sheets(7)
Set Treinamento = sourceWB.Sheets(10)
file_name = QuoteSTG.Range("A" + CStr(QuoteSTG.Range("B1").Value2)).Value2
QuoteSTG.Range("A" + CStr(QuoteSTG.Range("B1").Value2)).Value2 = ""
If splitter(2) = "Calibração" Then
loopH = splitter(26)
LoopCali = CInt(loopH)
sourceWB.Save
Header.Range("D6").Value2 = splitter(22)
Header.Range("D8").Value2 = splitter(12)
Header.Range("F4").Value2 = "AINT"
Header.Range("F3").Value2 = "EXW"
Header.Range("C2").Value2 = file_name
Header.Range("C4").Value2 = "Calibração"
Header.Range("L2").Value2 = "30"
Header.Range("K12").Value2 = Item.Subject '< criar string?
j = 40
For i = 1 To LoopCali
splitter2 = Split(splitter(j), "-")
AINT.Range("N7").Value2 = splitter2(0)
AINT.Range("N13").Value2 = splitter2(1)
j = j + 2
If splitter(j) <> "" Then
AINT.Range("N14").Value2 = splitter(j)
End If
j = j + 2
If splitter(j) <> "" Then
AINT.Range("N16").Value2 = splitter(j)
End If
j = j + 2
If splitter(j) <> "" Then
If splitter2(0) <> "RMT" Then
AINT.Range("N15").Value2 = splitter(j)
End If
End If
j = j + 2
If splitter(j) <> "" Then
AINT.Range("N17").Value2 = splitter(j)
End If
j = j + 2
xlApp.Application.Run "AINT.Cali_B_Click" '< calling the excel sub
Next i
End If
End If
End If
'Closing excel
MkDir "C:\Users\e1257539\Desktop\SMOBOT\" + file_name
sourceWB.SaveAs FileName:="C:\Users\e1257539\Desktop\SMOBOT\" + file_name + "\" + file_name
sourceWB.Close (False)
xlApp.Quit
Set xlApp = Nothing
Set sourceWB = Nothing
Set AINT = Nothing
Set QuoteSTG = Nothing
Set Header = Nothing
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
If Not sourceWB Is Nothing Then
sourceWB.Close (False)
End If
If Not xlApp Is Nothing Then
xlApp.Quit
End If
Set xlApp = Nothing
Set sourceWB = Nothing
Set AINT = Nothing
Set QuoteSTG = Nothing
Set Header = Nothing
End Sub
Turns out using xlApp.Application.Run "AINT.Cali_B_Click" or xlApp.Application.Run sourceWB.Name & "AINT.Cali_B_Click" left open references on the VBA code.
The way to call the code without lefting any open is using CallByName,
As in Call CallByName(AINT, "Cali_B_Click", VbMethod)
This way the VBA code can call the function and run as many times as needed without the current error.

How do I separate into a new cell in excel after every "-" in subject from outlook emails

I am trying to get the string after a word that gives me the needed data and all the phrase after every "-" into a new cell in excel except in RE: , where I omit "RE:" and only leave the TS... ticket ID.
This code works by selecting the emails in outlook and then running the macro for only that selected emails.
This is an example of a subject that has the
Example Subject
RE: TS001889493 - Translation failure - Inbound - ( VEXP/ HONCE/ Document Type 214 - Map AVE_NMHG_I_214_4010_XML_SAT - Error Conditional Relationship Error in N103 (0066) [ ref:_00D50c9MW._5000z1J3cG8:ref ]
Example of body
Dear Valued Trading Partner,
We received the attached 214 transactions from Sender ID: VEXP/ Receiver ID: HONCE that failed due to Conditional Relationship Error in the N1_03 (0066).
As per the map logic, If either N103 or N104 is present, then the other is required as they are in conditional relationship with each other.
But in the input file received, N104 value is missing hence the error.
Transaction Details: #4#
Attached
Please correct and resend the data.
Thank you,
Simon Huggs | Sass support - Basic
ref:_00D50c9MW._5000z1J3cG8:ref
What happens in the #num# is that it gets the sum of all these after making a match of the "TS" ticket ID.
This is the code I have up until now
Option Explicit
Sub WritingTicketNumberAndfailuresnew()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim rCount, STicket, SticketNumber As Long
Dim bXStarted As Boolean
Dim enviro As String
Dim strPath, SSubject As String
Dim currentExplorer As Explorer
Dim Selection As Selection
Dim olItem As Outlook.MailItem
Dim obj As Object
Dim strColS, strColB, sassupport, sMailDateReceived, SFrom As String
Dim Actions1, Actions2, Actions3, Actions4 As Boolean
Dim I, cnt, email_needed As Integer
' Get Excel set up
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Application.StatusBar = "Please wait while Excel source is opened ... "
Set xlApp = CreateObject("Excel.Application")
bXStarted = True
End If
On Error GoTo 0
'Open a specific workbook to input the data the path of the workbook under the windows user account
enviro = CStr(Environ("USERPROFILE"))
strPath = enviro & "\Documents\topthreeticket.xlsx"
Set xlWB = xlApp.Workbooks.Open(strPath)
Set xlSheet = xlWB.Sheets("Sheet1")
' Add column names
xlSheet.Range("A1") = "Email Subject"
xlSheet.Range("B1") = "Map Name"
xlSheet.Range("C1") = "Case Number"
xlSheet.Range("D1") = "No. Of Failures"
xlSheet.Range("E1") = "Date"
xlSheet.Range("F1") = "Week Number"
sassupport = "sassuport#sass.com"
On Error Resume Next
'Find the next empty line of the worksheet
rCount = xlSheet.Range("A" & xlSheet.Rows.Count).End(-4162).Row
'needed for Exchange 2016. Remove if causing blank lines.
rCount = rCount + 1
' get the values from outlook
Set currentExplorer = Application.ActiveExplorer
Set Selection = currentExplorer.Selection
For Each obj In Selection
Set olItem = obj
'collect the fields for ticket number and failure count
strColS = olItem.Subject
strColB = olItem.Body
SFrom = olItem.SenderEmailAddress
sMailDateReceived = olItem.ReceivedTime
Dim sFailures, stmp1, stmp2, stmp3 As String
Dim RegX As Object, Mats As Object
Dim Found As Boolean
' Check the number of failures from body
sFailures = "0"
stmp1 = strColB
Set RegX = CreateObject("VBScript.RegExp")
With RegX
.Global = True
.Pattern = "#\d+#"
Set Mats = .Execute(stmp1)
End With
If (RegX.Test(stmp1)) Then
stmp2 = Mats(0)
Found = True
stmp3 = Mid(stmp2, 2, Len(stmp2) - 2)
sFailures = stmp3
Else
With RegX
.Pattern = "#d\d+"
Set Mats = .Execute(stmp1)
End With
If (RegX.Test(stmp1)) Then
stmp2 = Mats(0)
Found = True
stmp3 = Mid(stmp2, 2, Len(stmp2) - 1)
sFailures = stmp3
End If
End If
Set Mats = Nothing
Set RegX = Nothing
Dim tmp As String
Dim RegX2 As Object, Mats1 As Object
tmp = strColS
Set RegX2 = CreateObject("VBScript.RegExp")
With RegX2
.Global = True
.Pattern = "TS00\d{7}"
Set Mats1 = .Execute(tmp)
End With
If (RegX2.Test(tmp)) Then
Set Mats1 = RegX2.Execute(tmp)
tmp = Mats1(0)
Else
With RegX2
.Pattern = "T.S\d{9}"
Set Mats1 = .Execute(tmp)
End With
If (RegX.Test(tmp)) Then
tmp = Mats1(0)
End If
End If
Set Mats1 = Nothing
Set RegX2 = Nothing
Dim tempticketnum, tmpdate As String
Dim ticketnumposition As Integer
'write them in the excel sheet
If SFrom = sassupport Then
xlSheet.Range("A" & rCount) = strColS
xlSheet.Range("B" & rCount) = tmp2
xlSheet.Range("C" & rCount) = tmp
xlSheet.Range("D" & rCount) = sFailures ' number of failures
xlSheet.Range("E" & rCount) = sMailDateReceived
rCount = rCount + 1
End If
Next
Set olItem = Nothing
Set obj = Nothing
Set currentExplorer = Nothing
Set xlSheet = Nothing
Set xlWB = Nothing
Set xlApp = Nothing
End Sub
You can use the SPLIT function in VBA, something like so
Sub x()
Dim s As String
Dim a() As String
s = "this-will-test-this-out"
a = Split(s, "-")
Range("a1").Resize(UBound(a) + 1, 1).Value = Application.Transpose(a)
End Sub

Resources