I have a sheet with Item names in the firs row.
I am using a Forloop to pass trough the cells in row 1 - i.
I use the value content of each cell to import a column from a .CSV file in the corresponding cell below it in row 2, by using j for that.
However, I have some .CSV files that are missing and I need to move on to the next cell in row 2, while moving on to the next cell in row 1. Basically skipping a column.
What I have so far is:
Dim FSO As Object
Dim Folder As Object
Dim File As String
Set FSO = CreateObject("Scripting.FileSystemObject")
Set Folder = FSO.GetFolder("C:\Users\Betty\AppData\Roaming\MetaQuotes\Terminal\B4D9BCD10BE9B5248AFCB2BE2411BA10\MQL4\Files")
For i = 2 To HCP.Cells(1, HCP.Columns.Count).End(xlToLeft).Column
Item = HCP.Cells(1, i).Value
FilePath = Folder & "\" & Item & "1440.CSV"
If Item = "" Or Dir(FilePath) = "" Then GoTo Continue
j = HCP.Cells(2, HCP.Columns.Count).End(xlToLeft).Column
With HCP.QueryTables.Add(Connection:="TEXT;" & FilePath, Destination:=HCP.Cells(2, j + 1))
.TextFileParseType = xlDelimited
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = True
.TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9, 9, 9, 9)
.Refresh BackgroundQuery:=False
End With
Continue:
Next
I need the column index of j to be corresponding to the column index of i at all times.
I would avoid using GoTo Continue. Just check the negative of your statements before entering the loop. You are also missing some End If statement in both your question and solution.
I left comments showing where the code will skip to if either Item or Dir are blank. Same result, just cleaner code.
For i = 2 To HCP.Cells(1, HCP.Columns.Count).End(xlToLeft).Column
Item = HCP.Cells(1, i).Value
FilePath = Folder & "\" & Item & "1440.CSV"
If Item <> "" Or Dir(FilePath) <> "" Then 'Test Here
j = HCP.Cells(2, HCP.Columns.Count).End(xlToLeft).Column
If j <> i Then j = i
With HCP.QueryTables.Add(Connection:="TEXT;" & FilePath, Destination:=HCP.Cells(2, j))
.TextFileParseType = xlDelimited
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = True
.TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9, 9, 9, 9)
.Refresh BackgroundQuery:=False
End With
End If 'Skips to here if either are blank.
Next i
I figured it out. This is what I am using now.
For i = 2 To HCP.Cells(1, HCP.Columns.Count).End(xlToLeft).Column
Item = HCP.Cells(1, i).Value
FilePath = Folder & "\" & Item & "1440.CSV"
If Item = "" Or Dir(FilePath) = "" Then GoTo Continue
j = HCP.Cells(2, HCP.Columns.Count).End(xlToLeft).Column
If j <> i Then j = i
With HCP.QueryTables.Add(Connection:="TEXT;" & FilePath, Destination:=HCP.Cells(2, j))
.TextFileParseType = xlDelimited
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = True
.TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9, 9, 9, 9)
.Refresh BackgroundQuery:=False
End With
Continue:
Next
And this is the result:
Please, feel free to make any other suggestions.
Solution 3: Nested ForLoop with Nested IfStatement
For i = 1 To BS.Cells(1, BS.Columns.Count).End(xlToLeft).Column
For j = 1 To BS.Cells(2, BS.Columns.Count - 1).End(xlToLeft).Column
Item = BS.Cells(1, i).Value
FilePath = Folder & "\" & Item & "1440.CSV"
If ((Item <> "") Or (Dir(FilePath) <> "") And (i = j)) Then
With BS.QueryTables.Add(Connection:="TEXT;" & FilePath, Destination:=BS.Cells(2, j + 1))
.TextFileParseType = xlDelimited
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = True
.TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9, 9, 9, 9)
.Refresh BackgroundQuery:=False
End With
End If
Next j
Next i
Solution 2: Nested Do Loop
Avoiding the "Continue" command, as it is not a VBA command.
For i = 2 To BS.Cells(1, BS.Columns.Count).End(xlToLeft).Column: Do
Item = BS.Cells(1, i).Value
FilePath = Folder & "\" & Item & "1440.CSV"
If Item = "" Or Dir(FilePath) = "" Then Exit Do
j = BS.Cells(2, BS.Columns.Count).End(xlToLeft).Column
If j <> i Then j = i
With BS.QueryTables.Add(Connection:="TEXT;" & FilePath, Destination:=BS.Cells(2, j))
.TextFileParseType = xlDelimited
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = True
.TextFileColumnDataTypes = Array(9, 9, 9, 9, 9, 1, 9, 9, 9, 9)
.Refresh BackgroundQuery:=False
End With
Loop While False: Next i
Please, Notice the : Do at the end of the end of the For i.
If one of the following conditions, i.e. Item = "" or Dir(FilePath) = "" is False , then the Do loop is exited. True if the Loop While False: Next i condition for the Do loop is stated.
The two conditions may also be presented as:
For i = 2 To BS.Cells(1, BS.Columns.Count).End(xlToLeft).Column: Do
If Item <> "" Or Dir(FilePath) <> "" Then
'Do something...
Else: Exit Do
End If
Loop While True: Next i
Having the Or condition in the If Item = "" Or Dir(FilePath) = "" Then Exit Do is mandatory as i may be Value <> " ", but the FilePath to the file may be non-existent i.e. Dir(FilePath) = " ", which will spit out an error as the previous I had.
The If j <> i Then j = i in this case is mandatory, as the For i is stated as =2 To, meaning that the loop starts from column 2.
This can be avoided by stating the For i loop as For i = 1 To. However this was the initial loop to get the job done.
Further j can be stated as j = BS.Cells(2, i), obtaining the value of i for a column index.
However, the If j <> i Then j = i statement is advisable for further assurance purposes.
In further search more solutions emerged.
See Solution 3: Nested For Loop with Nested If Statement
Related
Let's assume I have in xls a range filled like this:
ROW 1 |1|s|d|f|g|
ROW 2 |2|d|k|o|p|
ROW 3 |1|a|x|y|z|
I already have the code (vba) to work (parse data) on each row and put it into a txt file, but I'm not able to work only with rows that have, for example, "1" in the first column.
Almost tried most of the suggestion here posted without any luck...
Private Sub CommandButton1_Click()
lastRow = ActiveSheet.Range("B" & Rows.Count).End(xlUp).Row
SetValSrcNat = ""
Set fs = CreateObject("Scripting.FileSystemObject")
On Error GoTo fileexists
Set stream = fs.CreateTextFile("C:\Users\luciano.vigano\Documents \prova.txt", False, True)
For elabrow = 6 To lastRow
valInterface = Cells(elabrow, 3).Value
valProto = Cells(elabrow, 8).Value
valSrc = Cells(elabrow, 9).Value
If valSrc = "host" Then
valSrc = Cells(elabrow, 10)
Else
valSrc = Cells(elabrow, 9).Value & " " & Cells(elabrow, 10)
End If
valSrcNat = Cells(elabrow, 11).Value
If valSrcNat = "" Then
valSrcNat = SetValSrcNat
Else
valSrcNat = Cells(elabrow, 11).Value
End If
stream.Write ("Rule" & valRuleNumber & Chr(13) & Chr(10))
stream.WriteLine valInterface
Next elabrow
stream.Close
fileexists:
If Err.Number = 58 Then
MsgBox "File already Exists"
End If
End Sub
[enter link description here][1]I'm trying to search specific words in this text file in order to output it's line content in excel columns. The text file contains multiple sections. I'm able to output the first section of my text file but for some reasons I can't define a loop so I could retrieve every section of the file.
My code so far :
Sub test()
Dim myFile As String, text As String, textline As String, DDC As Integer, DDR As Integer, DDP As Integer, ADC As Integer, i As Integer, SE As Integer, SP As Integer, SG As Integer, j As Integer, v As Integer
myFile = "C:\Users\Seb\Desktop\text2.txt"
Open myFile For Input As #1
Do Until EOF(1)
Line Input #1, textline
text = text & textline
Loop
Close #1
i = 1
DDC = InStr(text, "Date de calcul")
DDR = InStr(text, "Date de retraite")
ADC = InStr(text, "Âge à la date du calcul")
SE = InStr(text, "Service d'emploi")
SP = InStr(text, "Service de participation")
SG = InStr(text, "Salaire gagné")
Cells(i + 1, 1).Value = Mid(text, DDC, 14)
Cells(i + 1, 2).Value = Mid(text, DDC + 36, 10)
Cells(i + 2, 1).Value = Mid(text, DDR, 16)
Cells(i + 2, 2).Value = Mid(text, DDR + 36, 10)
Cells(i + 3, 1).Value = Mid(text, ADC, 23)
Cells(i + 3, 2).Value = Mid(text, ADC + 36, 6)
Cells(i + 4, 1).Value = Mid(text, SE, 16)
Cells(i + 4, 2).Value = Mid(text, SE + 36, 6)
Cells(i + 5, 1).Value = Mid(text, SP, 24)
Cells(i + 5, 2).Value = Mid(text, SP + 36, 6)
For v = 0 To 10
j = v * 228
Cells(v + 7, 1).Value = Mid(text, SG + j, 24) + Mid(text, SG + 64 + j, 10) + "/ " + Mid(text, SG + 77 + j, 10)
Cells(v + 7, 2).Value = Mid(text, SG + 103 + j, 10)
Next v
End Sub
An exemple of my text file is available here: http://txt.do/5j2dq
As I mentioned before, I'm only able to output section 1 in excel. What my code should be in order to retrieve every sections of my text file?
After you have covered each section, simply remove the covered part from your text string, so that in the next iteration e.g. InStr(text, "Date 1") will find the Date 1 line of the next section.
Do While True
DDC = InStr(text, "Date 1")
If DDC = 0 Then
' no more sections - exit loop
Exit Do
End If
DDR = InStr(text, "Date 2")
ADC = InStr(text, "Age")
' ......
Next v
' remove the section that was just handled
text = Mid(text, SG + 30)
Loop
If you bring the TXT file in as Data ► External Data ► From Text, you can set period as an Other delimiter (with Treat consecutive delimiters as one being True).
Sub Import_Text()
Dim c As Long, myFile As String
myFile = "C:\Users\Seb\Desktop\text.txt"
With Worksheets("Sheet9") '<~~set this worksheet reference properly!
With .QueryTables.Add(Connection:="TEXT;" & myFile, _
Destination:=Range("$A$1"))
.Name = "TXT"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = True
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileOtherDelimiter = "."
.TextFileColumnDataTypes = Array(1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
'these will cleanup (trim) the results
For c = 1 To 2
With .Columns(c)
.TextToColumns Destination:=.Cells(1), DataType:=xlFixedWidth, _
FieldInfo:=Array(0, 1), TrailingMinusNumbers:=True
End With
Next c
End With
End Sub
There are two final Range.TextToColumns method with the xlFixedWidth option that simply trim off any rogue leading/railing spaces from the results.
I have written a visual basic macro to load a csv file into Excel that I use quite frequently.
Unfortunately, if the csv file contains quoted newlines, the result is different from what you would get if you opened the csv file directly with excel. Unlike the usual import facility, QueryTables.add() assumes any newline it runs into, whether quoted or not, is the end of the row.
Is there a way around this? I'd prefer a solution that did not involve pre-modifying the incoming csv files to remove the newlines, but I'm open to suggestions on that front as well. I do want to have newlines in the resulting excel file cells, though.
The relevant part of my macro:
Sub LoadMyFile()
' Query the table of interest
With ActiveSheet.QueryTables.Add(Connection:="TEXT;" _
& ThisWorkbook.Path & "\" & Range("A1").Value & ".csv", _
Destination:=Range("$A$2"))
.Name = ActiveSheet.Name
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlOverwriteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
Here's an example csv file with quoted newlines
"firstCol","secondCol"
"name1","data
one"
"name
2","data two"
The macro reads the file name (minus the .csv extension) from cell A1 and assumes the csv file is in the same directory as the excel file containing the macro.
I'm using 32 bit Office Professional 2010 on a windows 7 machine.
the import of such CSV files (newlines in data-points) works only with Workbooks.Open and only with CSVs in the locale format (delimiter, text-delimiter), the Excel is used.
Set wb = Workbooks.Open(Filename:="C:\Users\axel\Desktop\test.csv", Local:=True)
aData = wb.Worksheets(1).UsedRange.Value
lRows = UBound(aData, 1)
lCols = UBound(aData, 2)
With ActiveSheet
.Range(.Cells(1, 1), .Cells(lRows, lCols)).Value = aData
End With
wb.Close
Greetings
Axel
Edit: the code previously provided was actually designed with the specific example you provided in mind, with 2 columns and a relatively small number of data in the source CSV. I have reviewed the code below to fit other possible scenarios - also including a number of optimizations for runtime efficiency as well.
Note I am not used to using the seeking facilities relating to the Open method that I am relying on here, and I still have a couple misgivings re the way they actually work in some contexts tbh, but after running a couple tests the code looks to work just fine.
Sub csvImportbis()
Dim s As String
Dim i As Long
Dim j As Long
Dim a() As String
myfile = FreeFile
i = 1
j = 1
'ENTER YOUR PATH/FILE NAME HERE
Open "YOUR_PATH/FILENAME" For Input As #myfile
Do Until EOF(myfile)
Do
Input #myfile, s
cur = Seek(myfile)
Seek myfile, cur - 1
i = i + 1
Loop While input(1, #myfile) <> vbLf
ReDim a(1 To i - 1, 1 To 10000)
i = 1
Seek #myfile, 1
Do Until EOF(myfile)
Input #myfile, a(i, j)
i = i + 1
If i > UBound(a, 1) Then
i = 1
j = j + 1
End If
If j > UBound(a, 2) Then
ReDim Preserve a(1 To UBound(a, 1), 1 To UBound(a, 2) + 10000)
End If
Loop
Loop
Close #myfile
sup = j
ReDim Preserve a(1 To UBound(a, 1), 1 To sup)
'QUALIFY THE RANGE WITH YOUR WORKBOOK & WORKSHEET REFERENCES
Range("A1").Resize(sup, UBound(a, 1)) = WorksheetFunction.Transpose(a)
End Sub
I have the following issue. I have several source file to copy from into my summary sheet (the order of columns/rows can differ). Thus, I am trying to do some hard-coded check with a h/v-lookup combo. The code is the following:
For i = 2 To Row_number
'''' 1150 ''''
If (Cells(i, 42).Value = "1150") Then
If (WB_1150 Is Nothing) Then
Set WB_1150 = Workbooks.Open(directory & file_1150)
For Each wb In Workbooks
If (wb <> ThisWorkbook & wb <> WB_1150) Then
wb.Close savechanges = False
End If
Next wb
End If
bool_vlookup_result = IsError(Application.vlookup(ThisWorkbook.Sheets(sheet_name_swaption).Cells(i, 12), WB_1150.Sheets(1).range("V1:V" & Row_number), 1, False))
If (bool_vlookup_result = True) Then
ThisWorkbook.Activate
Sheets(sheet_name_swaption).Activate
Cells(i, 43).Value = "ERROR"
Next i
Else
row_index_result = Application.Match(Cells(i, 2), WB_1150.Sheets(1).range("V1:V" & Row_number), 0)
For j = 1 To 42
If (Cells(row_index_result, j) = "") Then
Next j
Else
bool_hlookup_result = IsError(Application.HLookup(ThisWorkbook.Sheets(sheet_name_swaption).Cells(i, j), WB_1150.Sheets(1).range(Cells(row_index_result, 1), Cells(row_index_result, 22)), 1, False))
If (bool_hlookup_result = True) Then
ThisWorkbook.Activate
Sheets(sheet_name_swaption).Activate
Cells(i, 43).Value = "ERROR"
Next i
End If
End If
Next j
ThisWorkbook.Activate
Sheets(sheet_name_swaption).Activate
Cells(i, 43).Value = "OK"
End If
End If
'''' End 1150 ''''
''' OTHER SOURCE FILES '''
Next i
I get the error Next without For, because as soon as I got an error I can skip to the following i/j. Any suggestions to solve/improve this? I know that there can be several ways to do those checks, but this is the most powerful (and most time-consuming though) instrument that I found. Many thanks in advance.
You can do it in such way:
For i = 1 To 10
If i = 3 Then GoTo Cont
Debug.Print i
Cont:
Next i
I am using the following VBA code to change the color of the rows in my spreadsheet every time the value in Column A changes (So that all entries with the same value in column A will be grouped by color. The spreadsheet is sorted by column A already so the items are already grouped, I just needed them colored).
Anyway, when I run this macro the rows are colored red & green (which are very bright and overwhelming colors for this purpose). I need something more subtle..
How do I change this? Or can I specify in my VBA code for it to use certain colors by rgb or color index? {I am using Excel 2007}
Sub colorize()
Dim r As Long, val As Long, c As Long
r = 1
val = ActiveSheet.Cells(r, 1).Value
c = 4
For r = 1 To ActiveSheet.Rows.Count
If IsEmpty(ActiveSheet.Cells(r, 1).Value) Then
Exit For
End If
If ActiveSheet.Cells(r, 1).Value <> val Then
If c = 3 Then
c = 4
Else
c = 3
End If
End If
ActiveSheet.Rows(r).Select
With Selection.Interior
.ColorIndex = c
.Pattern = xlSolid
End With
val = ActiveSheet.Cells(r, 1).Value
Next
End Sub
Run this program (credits here)
Sub colors56()
'57 colors, 0 to 56
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual 'pre XL97 xlManual
Dim i As Long
Dim str0 As String, str As String
For i = 0 To 56
Cells(i + 1, 1).Interior.ColorIndex = i
Cells(i + 1, 1).Value = "[Color " & i & "]"
Cells(i + 1, 2).Font.ColorIndex = i
Cells(i + 1, 2).Value = "[Color " & i & "]"
str0 = Right("000000" & Hex(Cells(i + 1, 1).Interior.Color), 6)
'Excel shows nibbles in reverse order so make it as RGB
str = Right(str0, 2) & Mid(str0, 3, 2) & Left(str0, 2)
'generating 2 columns in the HTML table
Cells(i + 1, 3) = "#" & str & "#" & str & ""
Cells(i + 1, 4).Formula = "=Hex2dec(""" & Right(str0, 2) & """)"
Cells(i + 1, 5).Formula = "=Hex2dec(""" & Mid(str0, 3, 2) & """)"
Cells(i + 1, 6).Formula = "=Hex2dec(""" & Left(str0, 2) & """)"
Cells(i + 1, 7) = "[Color " & i & ")"
Next i
done:
Application.Calculation = xlCalculationAutomatic 'pre XL97 xlAutomatic
Application.ScreenUpdating = True
End Sub
Output sample:
You can customize the colors palette by code, I think the page here will answer your question:
http://www.databison.com/index.php/excel-color-palette-and-color-index-change-using-vba/
Sub change_palette_color
dim color_index as long
color_index = 10
ActiveWorkbook.Colors(color_index) = RGB(128, 128, 128)
End sub
It turns out all I had to do is change a few numbers in the code i posted in my question. I bolded the numbers I had to change. These numbers correspond to the color ID (like what Belisarious put). NOTE: I had to put apostrohpes so that the VBA code wouldn't be recognized as VBA code (because if it is it won't bold the numbers). See the original question for the correct code.
Dim r As Long, val As Long, c As Long
'r = 1
'val = ActiveSheet.Cells(r, 1).Value
'c = 4
'For r = 1 To ActiveSheet.Rows.Count
If IsEmpty(ActiveSheet.Cells(r, 1).Value) Then
Exit For
End If
' If ActiveSheet.Cells(r, 1).Value <> val Then
If c = 3 Then
c = 4
Else
c = 3
End If
End If
ActiveSheet.Rows(r).Select
With Selection.Interior
.ColorIndex = c
.Pattern = xlSolid
End With
val = ActiveSheet.Cells(r, 1).Value
Next
End Sub