So, I have the code below in my "Thisworkbook" Module. I need it to run whenever the user saves the workbook. The code opens another workbook and transfers data into the new workbook.
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
'Exit Sub
On Error Resume Next
Dim Mas_loc As String
Mas_loc = "C:\Users\J03800\Documents\All Folders\Berry\MasterBerry.xlsx"
Dim n As Integer
Dim m As Integer
Dim x As Integer
Dim y As Integer
Dim PartNumber As String
Dim CageCode As String
Dim PartCage As String
Dim MI As Integer
Dim ChildWB As Workbook
Dim MasterWB As Workbook
Dim IsMatch As Boolean
Dim ChiMain As Worksheet
Dim MasMain As Worksheet
Set ChildWB = ActiveWorkbook
Set MasterWB = Workbooks.Open(Mas_loc)
Set ChiMain = ChildWB.Sheets("Main")
Set MasMain = MasterWB.Sheets("Main")
n = Application.CountA(ChiMain.Range("B:B")) + 1
m = Application.CountA(MasMain.Range("B:B")) + 1
ChildWB.Activate
For x = 3 To n
PartNumber = ChiMain.Cells(x, "B").Value
CageCode = ChiMain.Cells(x, "A").Value
CSMC = ChiMain.Cells(x, "J").Value
CMC = ChiMain.Cells(x, "L").Value
MassObj = ChiMain.Cells(x, "E").Value
ComObj = ChiMain.Cells(x, "H").Value
If Len(PartNumber) > 0 Then
If Len(CageCode) > 1 Then
PartNumber = "-" & Replace(Replace(PartNumber, CageCode & "-", ""), "-" & CageCode, "")
PartCage = "Cage-" & CageCode & "-" & PartNumber
Else
PartCage = "NoCage-" & PartNumber
End If
Else
PartCage = ""
End If
On Error GoTo NewPart
MatchAddress = Application.WorksheetFunction.Match(PartCage, MasMain.Range("K1:K" & m + 20), 0)
contin:
On Error Resume Next
If Len(CSMC) > 0 And Len(Replace(CSMC, "?", "")) = Len(CSMC) And Len(MasMain.Cells(MatchAddress, "E").Value) = 0 Then
MasMain.Cells(MatchAddress, "E").Value = CSMC
End If
If Len(CMC) > 0 And Len(Replace(CMC, "?", "")) = Len(CMC) And Len(MasMain.Cells(MatchAddress, "H").Value) = 0 Then
MasMain.Cells(MatchAddress, "H").Value = CMC
End If
If Len(MassObj) > 0 And Len(Replace(MassObj, "?", "")) = Len(MassObj) And Len(MasMain.Cells(MatchAddress, "C").Value) = 0 Then
MasMain.Cells(MatchAddress, "C").Value = MassObj
End If
If Len(MassObj) > 0 And Len(Replace(MasMain.Cells(MatchAddress, "C").Value, ComObj, "")) = MasMain.Cells(MatchAddress, "C").Value Then
MasMain.Cells(MatchAddress, "G").Value = MasMain.Cells(MatchAddress, "G").Value & Chr(10) & ComObj
End If
Next
MasterWB.Close SaveChanges:=True
Exit Sub
NewPart:
On Error Resume Next
m = m + 1
MatchAddress = m
MasMain.Cells(MatchAddress, "A").Value = ChiMain.Cells(MatchAddress, "A").Value
MasMain.Cells(MatchAddress, "B").Value = ChiMain.Cells(MatchAddress, "B").Value
MasMain.Cells(MatchAddress, "K").Value = PartCage
GoTo contin
End Sub
The problem seems to be that is is not opening MasterWB. As, when it bugs out, MasterWB is both not open and according to the code equal to nothing. What should I change?
Your code block looks fine - assuming the path specified in Mas_loc is accurate.
What errors are you getting when it "bugs out"?
Have you stepped through the code to see what is happening?
I would comment out the On Error Resume Next statement to stop masking any runtime errors.
I made the sub not private, then it worked
Related
I have below code.
In first loop the excel file is extracted from the SAP - loop with variable a.
In the second loop (loop with variable k) the invoice is extracted from SAP (takes the order number from earlier extracted excel file).
The number of the order is taken from the excel file and paste to order in SAP.
Sometimes it happens, that order is either not taken from excel or not paste in SAP and the field for the order is empty.
This situation try to generates all the orders for the Controlling Area, which is very time-consuming (in fact it lasts hours).
I tried to add this line of code before the paste to the order, but of no result
Application.Wait Now + TimeValue("0:00:05")
Have you met this in your coding and could help with this?
extracting the excel file from SAP
Sub invoice_extr()
'##########################
'zapisuje pliki xlsx ordery
'##########################
Application.ScreenUpdating = False
SheetSrc = "Input data"
On Error Resume Next
If Not IsObject(SAPApplication) Then
Set SapGuiAuto = GetObject("SAPGUI")
If Err.Number <> 0 Then Exit Sub
Set SAPApplication = SapGuiAuto.GetScriptingEngine
If Err.Number <> 0 Then Exit Sub
End If
If Not IsObject(Connection) Then
Set Connection = SAPApplication.Children(0)
If Err.Number <> 0 Then
MsgBox ("Please, open SAP!")
Exit Sub
Else
End If
End If
If Not IsObject(session) Then
Set session = Connection.Children(0)
End If
On Error GoTo 0
Application.Wait (Now + TimeValue("0:00:01") / 1.5)
Dim a As Double
Dim last_row As Double
last_row = Cells(Rows.Count, 1).End(xlUp).Row
Range("b2:c" & last_row).Select
Selection.ClearContents
Dim path As String
path = Cells(2, 6)
For a = 2 To last_row
'###########################################################
'####SPRAWDZA CZY JEST JUZ PLIK XLSX O TAKIEJ NAZWIE########
'###########################################################
Dim objFSO_november1 As Object
Dim objFolder_november1 As Object
Dim objFile_november1 As Object
Dim objFile1_november1 As Object
Dim aa_november1 As Integer
Dim bb_november1 As Integer
Set objFSO_november1 = CreateObject("Scripting.FileSystemObject")
Set objFolder_november1 = objFSO_november1.GetFolder(path)
bb_november1 = 0
For Each objFile1_november1 In objFolder_november1.Files
bb_november1 = bb_november1 + 1
Next objFile1_november1
Dim myArray_november1() As Variant
ReDim Preserve myArray_november1(bb_november1, 1)
aa_november1 = 0
For Each objFile_november1 In objFolder_november1.Files
myArray_november1(aa_november1, 1) = objFile_november1.name
aa_november1 = aa_november1 + 1
Next objFile_november1
Dim aa As Double
Dim zz As Double
zz = 0
For aa = 0 To aa_november1 - 1
Dim how_many As Double
how_many = Len(Cells(a, 1))
'MsgBox (Cells(a, 1))
'MsgBox (Left(myArray_november1(aa, 1), how_many))
'MsgBox (aa)
If (Cells(a, 1) * 1) = (Left(myArray_november1(aa, 1), how_many) * 1) Then
Cells(a, 2) = "Done"
zz = zz + 1
'MsgBox (zz)
End If
If zz <> 0 Then
GoTo line1
End If
Next aa
Erase myArray_november1
If zz <> 0 Then
GoTo line1
End If
session.findById("wnd[0]").maximize
session.findById("wnd[0]/tbar[0]/okcd").Text = "/Ns_alr_87013019"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/txt$6-KOKRS").Text = Cells(a, 4)
Workbooks("Saving_invoice.xlsm").Activate
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").Text = Cells(a, 1)
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").SetFocus
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").caretPosition = 6
session.findById("wnd[0]/tbar[1]/btn[8]").press
'On Error GoTo line1
On Error Resume Next
session.findById("wnd[0]/shellcont/shell/shellcont[2]/shell").hierarchyHeaderWidth = 453
session.findById("wnd[0]/usr/lbl[62,8]").SetFocus
session.findById("wnd[0]/usr/lbl[62,8]").caretPosition = 9
session.findById("wnd[0]").sendVKey 2
session.findById("wnd[1]/usr/lbl[1,2]").SetFocus
session.findById("wnd[1]/usr/lbl[1,2]").caretPosition = 4
session.findById("wnd[1]").sendVKey 2
'################################################################
'#############WYBIERA LAYOUT /MACRO##############################
'################################################################
session.findById("wnd[0]/tbar[1]/btn[33]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").currentCellRow = -1
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectColumn "VARIANT"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").contextMenu
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectContextMenuItem "&FILTER"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = "/MACRO"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 6
session.findById("wnd[2]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectedRows = "0"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").clickCurrentCell
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").currentCellColumn = "BELNR"
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectedRows = "0"
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").contextMenu
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectContextMenuItem "&XXL"
session.findById("wnd[1]/usr/cmbG_LISTBOX").SetFocus
session.findById("wnd[1]/usr/cmbG_LISTBOX").Key = "31"
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/ctxtDY_PATH").Text = path
Dim name As String
name = Cells(a, 1) & ".xlsx"
session.findById("wnd[1]/usr/ctxtDY_FILENAME").Text = name
session.findById("wnd[1]/usr/ctxtDY_FILENAME").caretPosition = 10
session.findById("wnd[1]/tbar[0]/btn[0]").press
'line1:
Application.Wait Now + TimeValue("0:00:05")
If Not Dir(path & name, vbDirectory) = vbNullString Then
Dim wB1 As Workbook
Dim ws1 As Worksheet
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
End With
Set wB1 = Workbooks.Open(path & name)
Set ws1 = wB.Sheets(1)
Application.Wait Now + TimeValue("0:00:05")
Workbooks(name).Activate
Workbooks(name).Close
Cells(a, 2) = "Done"
Else
Cells(a, 2) = "Please, check the order!"
End If
'Dim wB1 As Workbook
'Dim ws1 As Worksheet
'
' With Application
' .DisplayAlerts = False
' .EnableEvents = False
' .ScreenUpdating = False
' End With
'
' Set wB1 = Workbooks.Open(path & name)
' Set ws1 = wB.Sheets(1)
'
' Application.Wait Now + TimeValue("0:00:05")
'Workbooks(name).Activate
'
'Workbooks(name).Close
'
'Cells(a, 2) = "Checked"
line1:
Erase myArray_november1
Next a
Call invoice_extr_2
End Sub
extracting the invoice from SAP
Application.ScreenUpdating = False
SheetSrc = "Input data"
On Error Resume Next
If Not IsObject(SAPApplication) Then
Set SapGuiAuto = GetObject("SAPGUI")
If Err.Number <> 0 Then Exit Sub
Set SAPApplication = SapGuiAuto.GetScriptingEngine
If Err.Number <> 0 Then Exit Sub
End If
If Not IsObject(Connection) Then
Set Connection = SAPApplication.Children(0)
If Err.Number <> 0 Then
MsgBox ("Please, open SAP!")
Exit Sub
Else
End If
End If
If Not IsObject(session) Then
Set session = Connection.Children(0)
End If
On Error GoTo 0
Application.Wait (Now + TimeValue("0:00:01") / 1.5)
'####################################
'otwiera ordery i zapisuje faktury
'####################################
Workbooks("Saving_invoice.xlsm").Activate
Dim path As String
path = Cells(2, 6).Value
Dim last_row As Double
last_row = Cells(Rows.Count, 1).End(xlUp).Row
Dim i As Double
For i = 2 To last_row
Dim name2 As String
name2 = Cells(i, 1) & ".xlsx"
Dim wB2 As Workbook
Dim ws2 As Worksheet
If Not Dir(path & name2, vbDirectory) = vbNullString Then
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
End With
Set wB2 = Workbooks.Open(path & name2)
'Set ws2 = wB.Sheets(1)
Application.Wait Now + TimeValue("0:00:05")
Workbooks(name2).Activate
Else
GoTo line999999999
End If
Dim last_column As Integer
last_column = Cells(1, Columns.Count).End(xlToLeft).Column
'MsgBox (last_column)
Dim nr_kolumny As Long
nr_kolumny = Cells.Find(What:="Ref Document Number", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
If Cells(1, last_column) = "action" Then
Dim ostatnia_kolumna As Integer
ostatnia_kolumna = Cells.Find(What:="action", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
Else
ostatnia_kolumna = last_column + 1
End If
If Cells(1, last_column) = "action" Then
GoTo line2
Else
Cells(1, last_column + 1).Select
ActiveCell.FormulaR1C1 = "action"
End If
line2:
Dim k As Double
Dim last_row_document
last_row_document = Cells(Rows.Count, nr_kolumny).End(xlUp).Row - 2
For k = 2 To last_row_document
If Cells(k, ostatnia_kolumna) <> "Checked" Then
Workbooks("Saving_invoice").Activate
session.findById("wnd[0]").maximize
session.findById("wnd[0]/tbar[0]/okcd").Text = "/Ns_alr_87013019"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/txt$6-KOKRS").Text = Cells(i, 4)
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").Text = Cells(i, 1)
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").SetFocus
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").caretPosition = 6
session.findById("wnd[0]/tbar[1]/btn[8]").press
On Error Resume Next
session.findById("wnd[0]/shellcont/shell/shellcont[2]/shell").hierarchyHeaderWidth = 453
session.findById("wnd[0]/usr/lbl[62,8]").SetFocus
session.findById("wnd[0]/usr/lbl[62,8]").caretPosition = 9
session.findById("wnd[0]").sendVKey 2
session.findById("wnd[1]/usr/lbl[1,2]").SetFocus
session.findById("wnd[1]/usr/lbl[1,2]").caretPosition = 4
session.findById("wnd[1]").sendVKey 2
'#####################################################
'##############WYBIERA LAYOUT /MACRO##################
'#####################################################
session.findById("wnd[0]/tbar[1]/btn[33]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").currentCellRow = -1
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectColumn "VARIANT"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").contextMenu
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectContextMenuItem "&FILTER"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = "/MACRO"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 6
session.findById("wnd[2]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectedRows = "0"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").clickCurrentCell
'######################################################
'############TUTAJ FILTROWANIE PO DOKUMENCIE###########
'######################################################
Workbooks(name2).Activate
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").setCurrentCell -1, "REFBN"
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectColumn "REFBN"
session.findById("wnd[0]/tbar[1]/btn[29]").press
session.findById("wnd[1]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = Cells(k, nr_kolumny)
session.findById("wnd[1]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 8
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").currentCellColumn = "REFBN"
'session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectedRows = "0"
'session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").doubleClickCurrentCell
'###########################################################
'####SPRAWDZA CZY JEST JUZ PLIK O TAKIEJ NAZWIE#############
'###########################################################
Dim objFSO_november As Object
Dim objFolder_november As Object
Dim objFile_november As Object
Dim objFile1_november As Object
Dim aa_november As Integer
Dim bb_november As Integer
Set objFSO_november = CreateObject("Scripting.FileSystemObject")
Set objFolder_november = objFSO_november.GetFolder(path)
bb_november = 0
For Each objFile1_november In objFolder_november.Files
bb_november = bb_november + 1
Next objFile1_november
Dim myArray_november() As Variant
ReDim Preserve myArray_november(bb_november, 1)
aa_november = 0
For Each objFile_november In objFolder_november.Files
myArray_november(aa_november, 1) = objFile_november.name
aa_november = aa_november + 1
Next objFile_november
Dim z As Double
Dim how_digits As Double
how_digits = Len(Cells(k, nr_kolumny))
Dim s As Double
s = 0
For z = 0 To aa_november
If Left(myArray_november(z, 1), how_digits) = Cells(k, nr_kolumny) Then
s = s + 1
End If
Next z
Erase myArray_november
Dim h As Double
Dim o As Double
o = 0
For h = 2 To k
If Cells(h, nr_kolumny) = Cells(k, nr_kolumny) Then
o = o + 1
End If
Next h
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectedRows = o - 1 'tutaj nr linii po filtrowaniu
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").doubleClickCurrentCell
session.findById("wnd[0]/titl/shellcont/shell").pressContextButton "%GOS_TOOLBOX"
session.findById("wnd[0]/titl/shellcont/shell").selectContextMenuItem "%GOS_VIEW_ATTA"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").pressToolbarContextButton "&MB_FILTER"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").selectContextMenuItem "&FILTER"
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/cntlCONTAINER1_FILT/shellcont/shell").currentCellRow = 2
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/cntlCONTAINER1_FILT/shellcont/shell").selectedRows = "2"
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/btnAPP_WL_SING").press
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/btn600_BUTTON").press
session.findById("wnd[3]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = "Invoice"
session.findById("wnd[3]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 7
session.findById("wnd[3]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").currentCellColumn = "BITM_DESCR"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").selectedRows = "0"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").pressToolbarButton "%ATTA_EXPORT"
session.findById("wnd[2]/usr/ctxtDY_PATH").Text = path
If s = 0 Then
session.findById("wnd[2]/usr/ctxtDY_FILENAME").Text = Cells(k, nr_kolumny).Value & ".PDF"
Else
session.findById("wnd[2]/usr/ctxtDY_FILENAME").Text = Cells(k, nr_kolumny).Value & "-" & s + 1 & ".PDF"
End If
session.findById("wnd[2]/usr/ctxtDY_FILENAME").caretPosition = 5
session.findById("wnd[2]/tbar[0]/btn[0]").press
session.findById("wnd[1]/tbar[0]/btn[12]").press
Application.Wait Now + TimeValue("0:00:05")
Workbooks(name2).Activate
Cells(k, ostatnia_kolumna) = "Checked"
Workbooks(name2).Save
End If
Next k
Workbooks("Saving_invoice").Activate
Cells(i, 3) = "Checked"
Workbooks("Saving_invoice.xlsm").Save
Workbooks(name2).Save
Workbooks(name2).Close
line999999999:
Next i
Workbooks("Saving_invoice.xlsm").Activate
If Cells(1, 11) = "action" Then
Columns("K:K").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Delete Shift:=xlToLeft
End If
Cells(1, 1).Activate
Workbooks("Saving_invoice.xlsm").Save
MsgBox ("Done")
End Sub
Well Application.Wait "The time at which you want the macro to resume, in Microsoft Excel date format." So it only pauses your VBA code but not "lets wait till some lines finishes work and we will continue" not sure how to write correctly :D bad in English. But hope you understood.
I suggest you to use Immediate window, and check everything is in place(values) with Debug.Print "My value: " & variable, also VBA is tricky and trying to make people less code while it automatically converts string, int and other stuff which is not declared or misspelled. So make on top "Option Explicit", then declare everything what is not declared.
And delete "On Error Resume Next", cause you cant see first error.
I am totally new to VBA, looking for tips or hints to solve this question.
I am trying to loop through all the files in a folder and trying to split the filename into three parts that are separated by underscore and then paste those into a spreadsheet. After that, pivot it and count how many files there are in a new sheet.
For example, Filename : CA_File_20170810.txt
So it looks like this:
**IPA TYPE DATE Filename Filepath**
CA File 20170810
*IPA, Type, Date,filename, filepath are columns headers in excel.
Here is what I have in my code so far
Sub LoopingThroughFiles()
Dim f As String
Dim G As String
Dim File As Variant
Dim MyObj As Object
Dim MySource As Object
Dim FileName As Variant
Dim TypeName As Variant
Cells(1, 1) = "IPA"
Cells(1, 2) = "TYPE"
Cells(1, 3) = "DATE"
Cells(1, 4) = "FILENAME"
Cells(1, 5) = "FILEPATH"
Cells(2, 1).Select
f = Dir("C:\Users\kxc8574\Documents\VBA_Practice\")
G = Dir("C:\Users\kxc8574\Documents\VBA_Practice\")
If Right(f, 1) <> "\" Then
f = f + "\"
Cells(2, 1).Select
Do While Len(f) > 0
IpaName = Left(f, InStr(f, "_") - 1)
ActiveCell.Formula = IpaName
ActiveCell.Offset(1, 0).Select
f = Dir()
Loop
Do While Len(G) > 0
TypeName = Mid(G, InStr(G, "_") + 1, InStr(G, "File_") - InStr(G, "_") - 1)
ActiveCell.Formula = TypeName
ActiveCell.Offset(1, 0).Select
G = Dir()
Loop
End If
End Sub
I am missing a lot of things, not sure how to really continue. This code gives me an error "invalid procedure call" when it reaches the G = Dir()
Thanks for your help !!!
First, paste the text under "Explanation" into A1 of a worksheet. Then paste the code under "Code" into a module. Make sure the workbook is in the same directory as your .txt files. Then, run the macro. See animated gif for the result.
"Explanation"
This workbook contains a macro which will
1) Make a new sheet in this workbook named "Combined"
2) Open a copy of each .txt file located in the same directory as this workbook
3) extract the text between "_" characters
4) place the separated text into columns
5) count the number of .txt files processed
Note: Any sheet named "Combined" in this Workbook will be deleted
"Code"
Option Explicit
Sub CombineFiles()
Dim theDir As String, theFile As String
Dim sh As Worksheet, wk As Workbook, newSheet As Worksheet
Dim r As Range, parts() As String
Dim i As Long, s As String
Dim Done As Boolean, numFiles As Integer
Const ext = ".txt"
Err.Clear
theDir = ThisWorkbook.Path
'explain what program does
Worksheets("Program").Select
For i = 1 To 7
s = s & Cells(i, 1) & vbCr & vbCr
Next i
s = s & vbCr
s = MsgBox(s, vbYesNoCancel, "What this macro does")
If s <> vbYes Then End
For Each sh In Worksheets
If sh.Name = "Combined" Then
Application.DisplayAlerts = False
sh.Delete
Application.DisplayAlerts = True
End If
Next
Set newSheet = ThisWorkbook.Sheets.Add
newSheet.Name = "Combined"
'Loop through all files in directory with ext
s = Dir(theDir & "\*" & ext)
Set r = Range("A1")
r = "IPA"
r.Offset(0, 1) = "Type"
r.Offset(0, 2) = "Date"
r.Offset(0, 3) = "filename"
r.Offset(0, 4) = "filepath"
While s <> ""
numFiles = numFiles + 1
parts = Split(s, "_")
Set r = r.Offset(1, 0)
For i = 0 To 2
r.Offset(, i) = Replace(parts(i), ".txt", "")
Next i
r.Offset(, 3) = s
r.Offset(, 4) = theDir & "\" & s & ext
s = Dir()
Wend
MsgBox (numFiles & " files were processed.")
End Sub
Untested but should give you some idea:
Sub LoopingThroughFiles()
Const FPATH As String = "C:\Users\kxc8574\Documents\VBA_Practice\"
Dim f As String, i As Long, arr, sht As Worksheet
Set sht = ActiveSheet
sht.Cells(1, 1).Resize(1, 5).Value = _
Array("IPA", "TYPE", "DATE", "FILENAME", "FILEPATH")
f = Dir(FPATH & "*.txt") '<< only txt files
i = 2
Do While f <> ""
'split filename on underscore after replacing the ".txt"
arr = Split(Replace(f, ".txt", ""), "_", 3)
sht.Cells(i, 1).Resize(1, UBound(arr) + 1).Value = arr
sht.Cells(i, 4).Value = f
sht.Cells(i, 5).Value = FPATH
f = Dir() '<< next file
i = i + 1
Loop
End Sub
Untested but perhaps something like this??
Sub HashFiles()
Dim MyDir As String, MyIPA As Variant, MyType As Variant, MyDate As Variant, i As Integer, oFile As Object, oFSO As Object, oFolder As Object, oFiles As Object
MyDir = "C:\Users\kxc8574\Documents\VBA_Practice\"
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(MyDir)
Set oFiles = oFolder.Files
ReDim MyIPA(1 To oFiles.Count)
ReDim MyType(1 To oFiles.Count)
ReDim MyDate(1 To oFiles.Count)
i = 1
For Each oFile In oFiles
MyIPA(i) = Split(oFile.Name, "_")(0)
MyType(i) = Split(oFile.Name, "_")(1)
MyDate(i) = Split(oFile.Name, "_")(2)
i = i + 1
Next
Range("A2").Resize(UBound(MyIPA) + 1, 1) = Application.Transpose(MyIPA)
Range("B2").Resize(UBound(MyType) + 1, 1) = Application.Transpose(MyType)
Range("C2").Resize(UBound(MyDate) + 1, 1) = Application.Transpose(MyDate)
End Sub
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have the below code, but is very slow. Is there a way to improve it? I'm a beginner with VBA and would appreciate your help. What it does is it goes through a table and looks up in each worksheet for criteria to match and give values accordingly. Criteria differ by line in the initial range:
Sub TAB_REF_SETUP()
Dim TC As Integer
Dim TR As Integer
Dim C As Integer
Dim C2 As Integer
Dim R As Integer
Dim R2 As Integer
Dim TC2 As Integer
Dim TR2 As Integer
Dim CELL2 As Range
Dim CELL As Range
Dim RNG2 As Range
Dim RNG As Range
Dim WKS As Worksheet
Dim a As String
Dim xrow As Integer
Dim ycol As Integer
Dim CEllrow As Integer
Dim cellcol As Integer
Dim mincol As Integer
Dim mfrcol As Integer
Dim schrefc As Integer
Dim RBC As Integer
Dim RTC As Integer
Dim b As String
Dim CPC As Integer
Dim D As String
Dim AR As String
Dim StartTime As Double
Dim SecondsElapsed As Double
StartTime = Timer
'Application.ScreenUpdating = False
Application.AutoCorrect.AutoFillFormulasInLists = False
Application.CellDragAndDrop = False
Application.Calculation = xlCalculationManual
If ActiveSheet.AutoFilterMode = True Then
ActiveSheet.ShowAllData
Else
End If
C = Range("1:1").Find("Dist Classification").Column
If Range("1:1").Find("Schedule A Ref") Is Nothing Then
Columns(C + 1).Insert
Columns(C + 2).Insert
Columns(C + 3).Insert
Cells(1, C + 1).Value = "Schedule A Ref"
Cells(1, C + 2).Value = "Contract Name"
Cells(1, C + 3).Value = "Lookup Value"
schrefc = Range("1:1").Find("Schedule A Ref").Column
GoTo CellFill
Else
schrefc = Range("1:1").Find("Schedule A Ref").Column
If MsgBox("Ref Tab Exists. Do you want to proceed with further check?", vbYesNo, "Perform Further Check") = vbYes Then
If MsgBox("This will re-write column ""Schedule A Ref"". Do you wish to continue ?", vbYesNo, "Are you sure?") = vbYes Then
CellFill:
TC = Range("A1").End(xlToRight).Column
TR = Range("A1").End(xlDown).Row
Cells(1, TC + 1) = "Applicable Rebate"
Cells(1, TC + 2) = "Applicable Rebate Type"
Cells(1, TC + 3) = "Applicable Contract Price"
Cells(1, TC + 4) = "Actual Rebate $ for Line"
Cells(1, TC + 5) = "Rebate Owed"
Set RNG = Range(Cells(2, schrefc), Cells(Range("a1").End(xlDown).Row, schrefc))
mincol = Range("1:1").Find("MIN").Column
mfrcol = ActiveSheet.Range("1:1").Find("Mfr Name").Column
For Each CELL In RNG
CEllrow = CELL.Row
For Each WKS In Worksheets
If Not WKS.Range("1:1").Find("Schedule") Is Nothing And Not WKS.Range("1:3").Find(Cells(CEllrow, mfrcol)) Is Nothing And (InStr(1, WKS.Name, "fort", vbTextCompare) = 0 And InStr(1, WKS.Name, "report", vbTextCompare) = 0 And InStr(1, WKS.Name, "data", vbTextCompare) = 0) Then
C2 = WKS.Range("1:5").Find("Contract Name").Column
R2 = WKS.Range("1:5").Find("Contract Name").Row
TR2 = WKS.Range("1:5").Find("Contract Name").End(xlDown).Row
TC2 = C2
Set RNG2 = WKS.Range(WKS.Cells(R2 + 1, C2), WKS.Cells(TR2, C2))
xrow = WKS.Range("1:5").Find("SCC&Tab").Row
ycol = WKS.Range("1:5").Find("SCC&Tab").Column
RBC = WKS.Range("1:5").Find("Applicable Rebate").Column
RTC = WKS.Range("1:5").Find("Applicable Rebate Type").Column
CPC = WKS.Range("1:5").Find("Applicable Contract Price").Column
a = "=iferror(vlookup([#[Lookup Value]],indirect([#[Schedule A Ref]])," & RBC & ",false),iferror(vlookup([#[Dist Mfr. Item ID]]&[#[Contract Name]],indirect([#[Schedule A Ref]])," & RBC & ",false),""""))"
b = "=iferror(vlookup([#[Lookup Value]],indirect([#[Schedule A Ref]])," & RTC & ",false),iferror(vlookup([#[Dist Mfr. Item ID]]&[#[Contract Name]],indirect([#[Schedule A Ref]])," & RTC & ",false),""""))"
D = "=iferror(vlookup([#[Lookup Value]],indirect([#[Schedule A Ref]])," & CPC & ",false),iferror(vlookup([#[Dist Mfr. Item ID]]&[#[Contract Name]],indirect([#[Schedule A Ref]])," & CPC & ",false),""""))"
For Each CELL2 In RNG2
If InStr(1, CELL2, Cells(CEllrow, C), vbTextCompare) > 0 Then
Filler:
CELL.Value = "''" & WKS.Name & "'!" & WKS.Cells(xrow, ycol).Address & ":" & Cells(RNG2.End(xlDown).Row, RNG2.End(xlUp).End(xlToRight).Column).Address
Cells(CEllrow, C + 2).Value = CELL2
Cells(CEllrow, C + 3).Value = "=[#[Min]]&[#[Contract Name]]"
Cells(CEllrow, TC + 1) = a
Cells(CEllrow, TC + 2) = b
Cells(CEllrow, TC + 3) = D
If Cells(CEllrow, TC + 2).Value = "%D" Then
AR = "=[#[Applicable Rebate]]*[#[Applicable Contract Price]]*[#[case qty]]"
ElseIf Cells(CEllrow, TC + 2).Value = "$" Then
AR = "=[#[Applicable Rebate]]*[#[case qty]]"
ElseIf Cells(CEllrow, TC + 2).Value = "%P" Then
AR = "=[#[Applicable Rebate]]*[#[Total Vol]]"
Else
AR = "0"
End If
Cells(CEllrow, TC + 4) = AR
Cells(CEllrow, TC + 5) = "=[#[Actual Rebate $ for Line]]-[#[Committed - Rebate]]"
ElseIf InStr(1, CELL2, "nat", vbTextCompare) > 0 Then
GoTo Filler:
Else
End If
Next
Else
End If
Next
Next
Else
Exit Sub
End If
Else
Exit Sub
End If
End If
Application.AutoCorrect.AutoFillFormulasInLists = True
Application.Calculation = xlCalculationAutomatic
Application.CellDragAndDrop = True
Application.ScreenUpdating = True
SecondsElapsed = Round(Timer - StartTime, 2)
'Notify user in seconds
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub
Must do:
Uncomment from the top this:
Application.ScreenUpdating = False
A good idea to do:
Change all integer to long
Rewrite it in a way that you do not use goto statements. Install this -> http://www.oaltd.co.uk/indenter/indentpage.asp and indent. Or as mentioned in the comments, use the RubberDuck indenter.
The slowest part seems to be looping through cells. Use this instead:
Dim vData as Variant
Dim arrayIndex1 as Long, arrayIndex2 as Long
vData = Range(Cells(2, schrefc), Cells(Range("a1").End(xlDown).Row, schrefc))
For arrayIndex1 = lbound(vData) to ubound(vData)
For arrayIndex2 = lbound(vData,2) to ubound(vData,2)
'vData(arrayIndex1,arrayIndex2)
Next arrayIndex2
Next arrayIndex1
vData(arrayIndex1,arrayIndex2) is array counterpart of cells(row,col). By default arrays start from 0, so first arrayIndex1 will equal 0. To change default value to 1, use Option Base 1 at the top of the code.
Use With statement for multiple identical objects for better code clarity - and when inside a loop, also performance, for example instead of:
xrow = WKS.Range("1:5").Find("SCC&Tab").Row
ycol = WKS.Range("1:5").Find("SCC&Tab").Column
RBC = WKS.Range("1:5").Find("Applicable Rebate").Column
RTC = WKS.Range("1:5").Find("Applicable Rebate Type").Column
CPC = WKS.Range("1:5").Find("Applicable Contract Price").Column
use:
With WKS.Range("1:5")
xrow = .Find("SCC&Tab").Row
ycol = .Find("SCC&Tab").Column
RBC = .Find("Applicable Rebate").Column
RTC = .Find("Applicable Rebate Type").Column
CPC = .Find("Applicable Contract Price").Column
End With
Also try declaring variables like Dim TC As Long, TR As Long, C as Long so that declarations are not half of code's lines. Operating system converts integer to long anyway, so don't use integers. Use for example Cells(CEllrow, C).value instead of Cells(CEllrow, C).
I am trying to import FDF files(can be multiple) with VBA. When I run my code I got Subscript out of range error.
I know that the error suggests the worksheet it is looking for does not exist but I don't believe the code below actually defines the worksheet name which is probably the cause of the problem?
Can I have assistance in where, and what, code to insert to address this error? This is my code what I tried:
Sub FDFImport()
Dim OutSH As Worksheet
Dim Fname As Variant, f As Integer
Fname = Application.GetOpenFilename("FDF File,*.fdf", 1, "Select One Or More Files To Open", , True)
For f = 1 To UBound(Fname)
Open Fname(f) For Input As #1
Do While Not EOF(1)
Line Input #1, myvar
arr = Split(myvar, Chr(10))
arr2 = Split(arr(4), "/V")
If InStr(1, myvar, "(Contact)") > 0 Then
Set OutSH = Sheets("Contact")
outrow = OutSH.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
For i = 1 To 8
placer = InStr(1, arr2(i), ")")
OutSH.Cells(outrow, i).Value = Left(arr2(i), placer - 1)
Next i
Else
Set OutSH = Sheets("NoContact")
outrow = OutSH.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
For i = 1 To 12
placer = InStr(1, arr2(i), ")")
OutSH.Cells(outrow, i).Value = Left(arr2(i), placer - 1)
Next i
End If
Loop
Close #1
Sheets("Contact").Cells.Replace what:="(", replacement:=""
Sheets("NoContact").Cells.Replace what:="(", replacement:=""
Next f
End Sub
This is just a guess based on what you have posted but give this a try
Sub FDFImport()
Dim OutSH As Worksheet
Dim Fname As Variant, f As Integer
Dim myvar, arr, arr2, outrow, i, placer
Fname = Application.GetOpenFilename("FDF File,*.fdf", 1, "Select One Or More Files To Open", , True)
If VarType(Fname) = vbBoolean Then
Exit Sub
End If
For f = LBound(Fname) To UBound(Fname)
Open Fname(f) For Input As #1
Do While Not EOF(1)
Line Input #1, myvar
arr = Split(myvar, Chr(10))
arr2 = Split(arr(4), "/V")
If InStr(1, myvar, "(Contact)") > 0 Then
Set OutSH = Sheets("Contact")
outrow = OutSH.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
For i = 0 To 7
placer = InStr(1, arr2(i), ")")
OutSH.Cells(outrow, i).Value = Left(arr2(i), placer - 1)
Next i
Else
Set OutSH = Sheets("NoContact")
outrow = OutSH.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
For i = 0 To 11
placer = InStr(1, arr2(i), ")")
OutSH.Cells(outrow, i).Value = Left(arr2(i), placer - 1)
Next i
End If
Loop
Close #1
Sheets("Contact").Cells.Replace what:="(", replacement:=""
Sheets("NoContact").Cells.Replace what:="(", replacement:=""
Next f
End Sub
When you Split the array will be 0 based. Meaning you need loop through the array from 0 to X. When you are looping arr2 you have For i = 1 To 8 my guess is it should be For i = 0 To 7 you are doing the same for arr I have changed this is my answer.
I am new to Excel VBA and I really need your help. I have a code that will look for the duplicate values in Column A. This code will highlight the duplicate values. I want:
1.) This code to ONLY run when I click on a button.
2.) I would like to have (somewhere in the same worksheet), the number of duplicate results and a hyper link that when you click on it will direct you the duplicate result (this is because I have sometimes huge files that I need to validate). Here is the code I currently have:
Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim C As Range, i As Long
If Not Intersect(Target, Me.[A:A]) Is Nothing Then
Application.EnableEvents = False
For Each C In Target
If C.Column = 1 And C.Value > "" Then
If WorksheetFunction.CountIf(Me.[A:A], C.Value) > 1 Then
i = C.Interior.ColorIndex
f = C.Font.ColorIndex
C.Interior.ColorIndex = 3 ' Red
C.Font.ColorIndex = 6 ' Yellow
C.Select
MsgBox "Duplicate Entry !", vbCritical, "Error"
C.Interior.ColorIndex = i
C.Font.ColorIndex = f
End If
End If
Next
Application.EnableEvents = True
End If
End Sub
I would really appreciate it if you help me with this.
Add the code to Module1 Alt+F11
Option Explicit
Sub MyButton()
Dim RangeCell As Range, _
MyData As Range
Dim MyDupList As String
Dim intMyCounter As Integer
Dim MyUniqueList As Object
Dim lngLastRow As Long, lngLoopRow As Long
Dim lngWriteRow As Long
Set MyData = Range("A1:A" & Cells(Rows.Count, "A").End(xlUp).Row)
Set MyUniqueList = CreateObject("Scripting.Dictionary")
Application.ScreenUpdating = False
MyDupList = "": intMyCounter = 0
'// Find Duplicate
For Each RangeCell In MyData
If RangeCell <> "V" And RangeCell <> "R" Then
If Evaluate("COUNTIF(" & MyData.Address & "," & RangeCell.Address & ")") > 1 Then
'// Color. Change to suit RGB(141, 180, 226).
RangeCell.Interior.Color = RGB(141, 255, 226)
If MyUniqueList.exists(CStr(RangeCell)) = False Then
intMyCounter = intMyCounter + 1
MyUniqueList.Add CStr(RangeCell), intMyCounter
If MyDupList = "" Then
MyDupList = RangeCell
Else
MyDupList = MyDupList & vbNewLine & RangeCell
End If
End If
Else
RangeCell.Interior.ColorIndex = xlNone
End If
End If
Next RangeCell
'// Move duplicate from Column 1 to Column 7 = (G:G)
lngWriteRow = 1
lngLastRow = Cells(Rows.Count, 1).End(xlUp).Row
For lngLoopRow = lngLastRow To 1 Step -1
With Cells(lngLoopRow, 1)
If WorksheetFunction.CountIf(Range("A1:A" & lngLastRow), .Value) > 1 Then
If Range("G:G").Find(.Value, lookat:=xlWhole) Is Nothing Then
Cells(lngWriteRow, 7) = .Value
lngWriteRow = lngWriteRow + 1
End If
End If
End With
Next lngLoopRow
Set MyData = Nothing: Set MyUniqueList = Nothing
Application.ScreenUpdating = False
If MyDupList <> "" Then
MsgBox "Duplicate entries have been found:" & vbNewLine & MyDupList
Else
MsgBox "There were no duplicates found in " & MyData.Address
End If
End Sub
.
Add Module
Add Button
Assign to Macro