Excel VBA Macro jumps out of the loop , not getting why - vba

Can someone please confirm why my macro jumps out of loop. I am not getting why its happening.
My Input looks like this http://i.imgur.com/Y6XRBai.jpg
What I am trying is split the text and write to textfile from column D2 onwards using while loop, First file writes properly but when it starts writing second file either for loop or if condition breaks out and macro comes to line where strDir starts
Sub SplitTextAndSave()
'Macro to split text and write to text file
'Full name of File name will be Single quote + Prefix from B2 + ( + filename from C2 + )'
'Application.DisplayAlerts = False
Dim Val, splitVal As String
Dim reqNumTxt, totLn, reqNum, remChr, i As Integer
Dim wb As Workbook
Dim strFile, fileNm, strDir As String
Set Sheet = Excel.ActiveSheet
' Select where to place the files
Dim obj As Object
Dim path As String
Set obj = CreateObject("Shell.Application").browseforfolder(0, "Please Select Folder where TWS scripts will be created", 0)
On Error GoTo error_trap:
path = obj.self.path & "\"
error_trap:
'this is where it starts again when the loop breaks
strDir = path
filepre = Sheet.Cells(2, 2).Value
reqNum = Sheet.Cells(3, 2).Value
reqNumTxt = 0
Sheet.Cells(2, 4).Activate
Do While ActiveCell.Value <> ""
Set nextcell = ActiveCell.Offset(1, 0)
fileNm = ActiveCell.Offset(0, -1).Value
FileFullNm = strDir & "'" & filepre & "(" & fileNm & ")'"
Open FileFullNm For Output As #1
Val = ActiveCell.Value
totLn = Int(Len(Val) / reqNum)
remChr = Len(Val) Mod reqNum
If Len(Val) <= reqNum Then
Print #1, Val
Close #1
Else
For i = 1 To totLn
'I observed sometimes loop breaks here
splitVal = Left(Right(Val, Len(Val) - reqNumTxt), reqNum)
Print #1, splitVal
reqNumTxt = reqNumTxt + reqNum
Next i
If remChr = 0 Then
Close #1
Else
'most of the time loop break here when writing second file
splitVal = Left(Right(Val, Len(Val) - reqNumTxt), reqNum)
Print #1, splitVal
Close #1
End If
End If
nextcell.Select
Set currentcell = nextcell
'Next
Loop
MsgBox "Done"
'Application.DisplayAlerts = True
End Sub

I added 2 lines to your code and it runs without error. I set splitVal to null and reqNumTxt to zero.
Val = ActiveCell.Value
totLn = Int(Len(Val) / reqNum)
remChr = Len(Val) Mod reqNum
**splitVal = ""**
If Len(Val) <= reqNum Then
Print #1, Val
Close #1
Else
For i = 1 To totLn
'I observed sometimes loop breaks here
splitVal = Left(Right(Val, Len(Val) - reqNumTxt), reqNum)
Print #1, splitVal
reqNumTxt = reqNumTxt + reqNum
Next i
If remChr = 0 Then
Close #1
Else
'most of the time loop break here when writing second file
splitVal = Left(Right(Val, Len(Val) - reqNumTxt), reqNum)
Print #1, splitVal
Close #1
End If
End If
nextcell.Select
Set currentcell = nextcell
**reqNumTxt = 0**
Loop

Related

VBA How to get text from lines below when using Line Input?

I am trying to get copy information from an email saved as a .txt file to an excel sheet.
The issues I am running in to is when I use a Do Loop with the Line Input function I can not get information from text lines that are not on the current line. I would also like the code to copy the line containing the deliminator.
This is the code I am using:
intFreefile = FreeFile
Open ThisWorkbook.Path & "\temp567.txt" For Input As #intFreefile
lngRecordsInEmail = 0
Do Until EOF(intFreefile)
Line Input #intFreefile, strText
If InStr(1, strText, strDelimiter) > 0 Then
If InStrRev(1, strText, strDelimiter) = 1 Then
' if last character in line = deliminator then
' how do i get the text on 2 lines below?
Else
ws.Cells(lngRow, 1).Value = strText
End If
If blColourCell Then
ws.Cells(lngRow, 1).Interior.ColorIndex = 35
End If
strText2 = strText2 + 1
lngRow = lngRow + 1
lngTotalRecords = lngTotalRecords + 1
lngRecordsInEmail = lngRecordsInEmail + 1
End If
Loop
Close
My favorite method which is also faster than looping through the file contents is to read the entire text from the file into an array in one go and then work with the array. This will also give you more control to retrieve text from the 2 lines that you want.
Is this what you are trying? (Untested)
Dim MyData As String, strData() As String
Dim i As Long
intFreefile = FreeFile
'~~> Open file and read it on one go
Open ThisWorkbook.Path & "\temp567.txt" For Binary As #intFreefile
MyData = Space$(LOF(1))
Get #intFreefile, , MyData
Close #intFreefile '<~~ Close the text file after reading from it
'~~> This array has the entire contents from the text file
strData() = Split(MyData, vbCrLf)
For i = LBound(strData) To UBound(strData)
'~~> Last character in line = deliminator
If Right(strData(i), 1) = strDelimiter Then
Debug.Print strData(i)
Debug.Print strData(i + 1)
Debug.Print strData(i + 2)
'~~> Else if the deliminator is somewhere else
ElseIf InStr(1, strData(i), strDelimiter) Then
Debug.Print strData(i)
End If
Next i

how to get multiple value (how get second matching data)

i am working on this code below
i try to get data from another workbooks sheet1
my problem is there are two ” Financial Depth” with different value in workbook sheet1
how i can get them two different cell
example
Financial Depth=10.000
Financial Depth=24.000
this code get first value .(Financial Depth=10.000)......
Sub Balance()
Dim I As Integer
Dim myfile As String
Pathname = “E:\test\”
I = 1
myfile = Dir(Pathname & “*.xls”)
Cells(1, I) = myfile
StartingPoint:
I = I + 1
myfile = Dir
Cells(I, 1) = myfile
If myfile “” Then GoTo StartingPoint
I = I – 1
For K = 1 To I
‘On Error Resume Next
‘ *** workbook name***
Filename = Cells(K, 1)
Workbooks.Open (Pathname & Filename)
‘ *** company name ***
Cells(K, 2) = Workbooks(Filename).Worksheets(“Sheet1″).Cells(1, 1)
‘ *** Financial Depth***
Cells(K, 3) = ” Financial Depth”
For g = 1 To 220
If Workbooks(Filename).Worksheets(“Sheet1″).Cells(g, 1) = ” Financial Depth” Then
Cells(K, 4) = Workbooks(Filename).Worksheets(“Sheet1″).Cells(g, 3)
Exit For
End If
Next g
Workbooks(Filename).Saved = True
Workbooks(Filename).Close
Next k
End Sub
This should work for you
Sub Balance()
Dim I As Integer
Dim myfile As String
Dim m as Integer
m = 4
Pathname = “E:\test\”
I = 1
myfile = Dir(Pathname & “*.xls”)
Cells(1, I) = myfile
StartingPoint:
I = I + 1
myfile = Dir
Cells(I, 1) = myfile
If myfile “” Then GoTo StartingPoint
I = I – 1
For K = 1 To I
‘On Error Resume Next
‘ *** workbook name***
Filename = Cells(K, 1)
Workbooks.Open (Pathname & Filename)
‘ *** company name ***
Cells(K, 2) = Workbooks(Filename).Worksheets(“Sheet1″).Cells(1, 1)
‘ *** Financial Depth***
Cells(K, 3) = ” Financial Depth”
For g = 1 To 220
If Workbooks(Filename).Worksheets(“Sheet1″).Cells(g, 1) = ” Financial Depth” Then
Cells(K, m) = Workbooks(Filename).Worksheets(“Sheet1″).Cells(g, 3)
m = m +1
End If
Next g

Subscript out of range error in VBA

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.

Questions regarding Dir VBA

I'm having a set of files which I want to loop through with the filenames: Budget 2015, Budget 2016, Budget 2017 up to 2022. I loop through them using Dir.
Dim OpenWb as workbook
path = Dir("C:\pathtofile\Budget 20??.xlsx") 'Using the ? Dir Wildcard
filepath = "C:\pathtofile\" 'Since Dir returns file name, not the whole path
myHeadings = Split("Januari,Februari,Mars,April,Maj,Juni,Juli,Augusti,September,Oktober,November,December", ",")
j = 0
Do While Len(path) > 0
i = 0
If Dir = "Budget 2014.xlsx" Then
j=0
Else
For i = 0 To UBound(myHeadings)
Set openWb = Workbooks.Open(filepath & path)
MsgBox Len(path)
Set openWs = openWb.Sheets(myHeadings(i))
If openWs.Range("C34") = 0 Then
currentWb.Sheets("Indata").Cells(70, i + 27 + 12 * (j + 1)).Value = ""
Else
currentWb.Sheets("Indata").Cells(70, i + 27 + 12 * (j + 1)).Value = openWs.Range("C34")
End If
Next i
End if
path = Dir
j= j + 1
Loop
The trouble is that in the filepath there's also a file called Budget 2014, which I do not want to loop through because 1) It's not necessary, the values are computed already and 2) Since it screws up my indices in the loop
Updated my code. But using msgBox (path) inside the for i = 0... loop returns "Budget 2014.xlsx" which I did not want to loop, and hence this "messes" with my j subscript.
You could make use of the Year method. Something like,
Dim OpenWb as workbook, yearNo As Long, filepath As String
filepath = "C:\pathtofile\"
yearNo = Year(Date())
path = Dir("C:\pathtofile\Budget " & yearNo & ".xlsx")
Do While Len(path) > 0
set OpenWb = Workbooks.open(filepath & path) ' Since Dir only returns file name
'Doing some things
yearNo = yearNo + 1
path = Dir("C:\pathtofile\Budget " & yearNo & ".xlsx")
Loop
You could also try this:
Dim OpenWb as workbook
path = Dir("C:\pathtofile\Budget 20??.xlsx") 'Using the ? Dir Wildcard
filepath = "C:\pathtofile\" 'Since Dir returns file name, not the whole path
myHeadings = Split("Januari,Februari,Mars,April,Maj,Juni,Juli,Augusti,September,Oktober,November,December", ",")
j = 0
Do While Len(path) > 0
i = 0
'change here: only execute if it's NOT the file you're NOT after
If Dir <> "Budget 2014.xlsx" Then
For i = 0 To UBound(myHeadings)
Set openWb = Workbooks.Open(filepath & path)
MsgBox Len(path)
Set openWs = openWb.Sheets(myHeadings(i))
If openWs.Range("C34") = 0 Then
currentWb.Sheets("Indata").Cells(70, i + 27 + 12 * (j + 1)).Value = ""
Else
currentWb.Sheets("Indata").Cells(70, i + 27 + 12 * (j + 1)).Value = openWs.Range("C34")
End If
Next i
'Change here: only update path & j if you processed the file
path = Dir
j= j + 1
End if
Loop
Sub M_snb()
c00 = "C:\pathtofile\"
sn = Application.GetCustomListContents(4)
c01 = Dir(c00 & "Budget 20*.xlsx")
Do While c01 <> ""
If c01 <> "Budget 2014.xlsx" Then
With GetObject(c00 & c01)
For j = 0 To UBound(sn)
c02 = c02 & "|" & IIf(.Sheets(sn(j)).Range("C34") = 0, "", .Sheets(sn(j)).Range("C34"))
Next
.Close 0
End With
End If
c01 = Dir
Loop
sp = Split(Mid(c02, 2), "|")
ThisWorkbook.Sheets("Indata").Cells(70, 51).Resize(, UBound(sp)) = sp
End Sub

Excel 2010 - VBA code to Write Formatted Numbers to CSV

I'm working on a 5 sheet workbook, where a button named ExportCSV on sheet 5 exports data on sheet 3. More specifically, the button runs a VBA code that goes row by row and checks the first 3 cells for data. If any of the first three cells have data, then the whole row is selected. After all rows with data are selected, the data is written row by row to a CSV file (the file itself is semicolon-delimited, however).
The problem that I'm having is that some cell formatting is being copied over, but some is not. For example, values in cells formatted for Accounting with a $ are formatted correctly, meaning "$12,345,678.90" shows up as "$12,345,678.90." However, values in cells formatted as Accounting but without $ are not being written to the csv correctly, meaning "12,345,678.90" is being written as "12345678.9."
Below is the Macro in question.
Dim planSheet As Worksheet
Dim temSheet As Worksheet
Private Sub ExportCSV_Click()
Dim i As Integer
Dim j As Integer
Dim lColumn As Long
Dim intResult As Integer
Dim strPath As String
On Error GoTo Errhandler
Set temSheet = Worksheets(3)
i = 2
Do While i < 1001
j = 1
Do While j < 4
If Not IsEmpty(temSheet.Cells(i, j)) Then
temSheet.Select
lColumn = temSheet.Cells(2, Columns.Count).End(xlToLeft).Column
temSheet.Range(temSheet.Cells(2, 1), temSheet.Cells(i, lColumn)).Select
End If
j = j + 1
Loop
i = i + 1
Loop
Application.FileDialog(msoFileDialogFolderPicker).InitialFileName = Application.ActiveWorkbook.Path
Application.FileDialog(msoFileDialogFolderPicker).Title = "Select a Path"
Application.FileDialog(msoFileDialogFolderPicker).ButtonName = "Select Path"
intResult = Application.FileDialog(msoFileDialogFolderPicker).Show
If intResult <> 0 Then
'dispaly message box
strPath = Application.FileDialog(msoFileDialogFolderPicker).SelectedItems(1)
End If
Dim X As Long, FF As Long, S() As String
ReDim S(1 To Selection.Rows.Count)
For X = 1 To Selection.Rows.Count
S(X) = Join(WorksheetFunction.Transpose(WorksheetFunction.Transpose(Selection.Rows(X).Value)), ";")
Next
FF = FreeFile
FilePath = strPath & "\Data" & Format(Now(), "yyyyMMddhhmmss") & ".csv"
Open FilePath For Output As #FF
Print #FF, Join(S, vbNewLine)
Close #FF
Errhandler:
...Error Handling Code omitted
End Sub
I need to be able to copy over the exact formatting of the cells. Converting the no-$ cells to $ cells won't work because the values without $ are being used for a calculation later on in the process that can handle the commas, but not a $, and I can't change the code for the later calculation (proprietary plug-in doing the calculation.) Also, the rows have mixed content, meaning some values in the row are text instead of numbers.
I ended up following David Zemens' advice and overhauled the section that was For X = 1 to Selection.Rows.Count See below.
For X = 1 To Selection.Rows.Count
For Y = 1 To Selection.Columns.Count
If Y <> Selection.Columns.Count Then
If IsNumeric(temSheet.Cells(X + 1, Y).Value) Then
If temSheet.Cells(X + 1, Y).Value = 0 Then
S(X) = S(X) & ";"
Else
S(X) = S(X) & Replace(temSheet.Cells(X + 1, Y).Text, " ", "") & ";"
End If
Else
S(X) = S(X) & Trim(temSheet.Cells(X + 1, Y).Text) & ";"
End If
Else
If IsNumeric(temSheet.Cells(X + 1, Y).Value) Then
If temSheet.Cells(X + 1, Y).Value <> 0 Then
S(X) = S(X) & Replace(temSheet.Cells(X + 1, Y).Text, " ", "")
End If
Else
S(X) = S(X) & Trim(temSheet.Cells(X + 1, Y).Text)
End If
End If
Next
Next
Some more formatting was necessary. It goes cell by cell, purposefully skipping the first row of the sheet. The .Text property of some of the cells returned empty space before the value or between the $ and value, so it had to be removed. Trim removes leading and ending spaces while Replace replaces all spaces in the export.