Get only Sub names - excel

Using below code I am getting both Sub names and functions name, but I want only Sub names excluding function names, please suggest me for this, it will be really helpful for me
Sub ListMacros()
Dim VBComp As VBComponent
Dim VBCodeMod As CodeModule
Dim oListsheet As Object
Dim StartLine As Long
Dim ProcName As String
Dim iCount As Integer
Application.ScreenUpdating = False
On Error Resume Next
Set oListsheet = ActiveWorkbook.Worksheets.Add
iCount = 1
oListsheet.[a1] = "Macro"
For Each VBComp In ThisWorkbook.VBProject.VBComponents
Set VBCodeMod = ThisWorkbook.VBProject.VBComponents(VBComp.Name).CodeModule
With VBCodeMod
StartLine = .CountOfDeclarationLines + 1
Do Until StartLine >= .CountOfLines
oListsheet.[a1].Offset(iCount, 0).Value = _
.ProcOfLine(StartLine, vbext_pk_Proc)
iCount = iCount + 1
StartLine = StartLine + _
.ProcCountLines(.ProcOfLine(StartLine, _
vbext_pk_Proc), vbext_pk_Proc)
Loop
End With
Set VBCodeMod = Nothing
Next VBComp
Application.ScreenUpdating = True
End Sub

Please add this lines:
If InStr(.Lines(StartLine, 2), "Function") = 0 Then
iCount = iCount + 1
End If
'2 lines because sometimes it returns "" for only a line (from unknown reasons)...
after
oListsheet.[a1].Offset(iCount, 0).Value = _
.ProcOfLine(StartLine, vbext_pk_Proc)
Edited, to return the standard module type, too:
If InStr(.Lines(StartLine, 2), "Function") = 0 Then
If VBComp.Type = 1 Then
oListsheet.[a1].Offset(iCount, 1).Value = VBComp.Name
End If
iCount = iCount + 1
End If

' *****************************************************************************************
' Connect to Siebel
' *****************************************************************************************
Function WriteCell(iRow As Integer, iCol As Integer, iColor As Integer, Msg As String)
ViewsSheet.Cells(iRow, iCol).Font.ColorIndex = iColor
ViewsSheet.Cells(iRow, iCol).Value = Msg
End Function
Sub ListMacros()
Application.DisplayAlerts = False
ActiveWorkbook.Save
Dim VBComp As VBComponent
Dim VBCodeMod As CodeModule
Dim oListsheet As Object
Dim StartLine As Long
Dim ProcName As String
Dim iCount As Integer
Application.ScreenUpdating = False
On Error Resume Next
Set oListsheet = ActiveWorkbook.Worksheets.Add
oListsheet.Name = "MacroList"
iCount = 0
oListsheet.[a1] = ""
For Each VBComp In ThisWorkbook.VBProject.VBComponents
Set VBCodeMod = ThisWorkbook.VBProject.VBComponents(VBComp.Name).CodeModule
With VBCodeMod
StartLine = .CountOfDeclarationLines + 1
Do Until StartLine >= .CountOfLines
oListsheet.[a1].Offset(iCount, 0).Value = .ProcOfLine(StartLine, vbext_pk_Proc)
'If InStr(.Lines(StartLine, 2), "Function") = 0 Then
iCount = iCount + 1
'End If
StartLine = StartLine + .ProcCountLines(.ProcOfLine(StartLine, vbext_pk_Proc), vbext_pk_Proc)
Loop
End With
Set VBCodeMod = Nothing
Next VBComp
Application.ScreenUpdating = True
Dim FilePath As String
Dim CellData As String
Dim LastCol As Long
Dim LastRow As Long
Dim i As Long
Dim j As Long
LastCol = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Column
LastRow = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
CellData = ""
FilePath = "E:\Dir\Excel\MacroTxt\\MacroList2.txt"
Open FilePath For Output As #2
For i = 1 To LastRow
For j = 1 To LastCol
If j = LastCol Then
CellData = CellData + Trim(ActiveCell(i, j).Value)
Else
CellData = CellData + Trim(ActiveCell(i, j).Value) + ","
End If
Next j
Write #2, CellData
CellData = ""
Next i
Close #2
Application.DisplayAlerts = False
End Sub

Related

Ubound and In bound runtime error 9 vba( error only on one system works fine on all the other systems)

VBA runtime 9 error subscript out of range on only one system works fine on all the systems( error near ubound and lbound)
This code worked fine for years later it is giving an error on only one system.
I have tried updating the excel software and changing the data types for irow and icolumn. Any help is appreciated.
Sub TechHR_Refresh_Staffing(sDate As String, sLocationName As String)
Dim ws As Worksheet
Dim rng As Range
Dim sOrderDate As String
Dim sProtocolHost As String, sQueryServlet As String, sEditType As String,
sMeasure As String
Dim sSheet As String, sTable As String
Dim sURL As String, sPost As String
Dim iRow As Long, iCol As Long, i As Long, j As Long
If (sLocationName = kLocation_Lamar1NRD) Then
sSheet = kSheet_StaffingData
sTable = kTable_StaffingTotals
ElseIf (sLocationName = kLocation_Lamar2NRD) Then
sSheet = kSheet_StaffingDataL2
sTable = kTable_StaffingTotalsL2
ElseIf (sLocationName = kLocation_Lamar1CP) Then
sSheet = kSheet_StaffingDataCP
sTable = kTable_StaffingTotalsCP
Else
sSheet = kSheet_StaffingDataCPL2
sTable = kTable_StaffingTotalsCPL2
End If
Set ws = MIRGetNamedSheet(sSheet)
ws.Columns(1).NumberFormat = "m/d/yyyy h:mm"
ws.Columns(2).NumberFormat = "#"
ws.Columns(3).NumberFormat = "#"
ws.Columns(4).NumberFormat = "0"
ws.Columns(5).NumberFormat = "0"
ws.Columns(6).NumberFormat = "0"
sOrderDate = Replace(sDate, "-", "")
sURL = kProtocolHost + kQueryServlet
sPost = "__JSScript=SOS_TempCalculator&__orderdate=" + sOrderDate +
"&__location=" + sLocationName
If WQ_RunQuery(sURL, sPost) Then
'Reading results and displaying them
Dim aResults() As String
Dim bHasResults As Boolean
iRow = 0
While WQ_ParseResults(aResults)
For i = LBound(aResults, 1) To UBound(aResults, 1)
iRow = iRow + 1
iCol = 1
For j = LBound(aResults, 2) To UBound(aResults, 2)
ws.Cells(iRow, iCol).Value = aResults(i, j)
iCol = iCol + 1
Next j
Next i
bHasResults = True
Wend
'Code error in the line below
iRow = UBound(aResults, 1) - LBound(aResults, 1) + 1
iCol = UBound(aResults, 2) - LBound(aResults, 2) + 1
Set rng = ws.Range(ws.Cells(1, 1), ws.Cells(iRow, iCol))
ws.ListObjects.Add(xlSrcRange, rng, , xlYes).Name = sTable
End If
Exit Sub
End Sub

How do I figure out if my temporary folder is overloading? (Apologies on the length)

I have a macro that threw the below error, and I have a theory why, but am having trouble finding any literature to back it up. Pages I found are typically people posting silly mistakes with incorrect variable types.
I don't think there's anything wrong with the code, I just think the nature of the task takes too long, therefore overloading the temp folder. Per TechWalla (emphasis mine):
The Runtime Error 6 occurs in the Visual Basic program. It is an overflow issue that can occur when the Visual Basic program attempts to store too much data in the temporary folders area. Runtime files help Windows translate a program's language into Windows language so the program runs faster. You can get the Runtime Error 6 message for several reasons. One reason is that you are using a backslash instead of a forward slash in one of your calculations. Other reasons include an overloaded temporary folder, outdated software or a registry error.
(Caveat: I haven't seen this explanation elsewhere and can't vouch for how reliable Techwalla is. I don't know if I'm not searching with the right keywords, but like I said, I haven't found much of anything other than code-specific forum posts.)
Is there a way to determine if this is the case? I outline below why I think this is what's causing the error, which might help, but doesn't change the question. If this is the case, is there a way to find out? And if so, is there a way to prevent it?
(I'll be running it again tonight now that I've used a registry cleaner that found 1GB, though I don't know how much was from Excel. For reference, my C: drive has 180GB free...)
EDIT: Removing code, because I'm asking not asking about that, but whether or not the temporary folder overloading could actually cause this.
EDIT2: After being swayed by the people, I am re-adding the code. And I know, it's not efficient. Thank you for the suggestions though.
EDIT3 (LAST ONE, I SWEAR): Though I realize the description above specifically mentions Visual Basic, which is not VBA, I'm keeping it in as I know Excel uses/creates temporary files, and has memory limits, which is ultimately what I'm curious about.
Sub getCBU()
Dim rowCount As Long, newRow(1 To 17) As Variant, compareRow(1 To 17) As Variant, nextFile As String, s As Long
Dim location As String, lastRow As Long, match As Boolean, startTime As Double, secondsElapsed As String
location = "C:\Users\swallin\Documents\CBU History\"
nextFile = Dir(location & "CBU*")
rowCount = 2
startTime = Timer
Do While nextFile <> ""
Workbooks.Open (location & nextFile)
lastRow = Workbooks(nextFile).Worksheets(1).Cells(Rows.Count, 1).End(xlUp).Row
For s = 18 To lastRow
match = True
For x = 1 To 17
newRow(x) = Workbooks(nextFile).Worksheets(1).Cells(s, x)
Next x
For y = 2 To rowCount
If Val(newRow(11)) = Val(ThisWorkbook.Worksheets(1).Cells(y, 11)) Then
For j = 1 To 17
compareRow(j) = ThisWorkbook.Worksheets(1).Cells(y, j).Value
Next j
For v = 1 To 17
If Val(compareRow(v)) <> Val(newRow(v)) Then
match = False
Exit For
Else
match = True
End If
Next v
If match = True Then
Exit For
End If
Else
match = False
End If
Next y
y = 2
If match = False Then
rowCount = rowCount + 1
For t = 1 To 17
ThisWorkbook.Worksheets(1).Cells(rowCount, t) = newRow(t)
Next t
End If
Next s
s = 18
Workbooks(nextFile).Close
nextFile = Dir()
Loop
secondsElapsed = Format((Timer - startTime) / 86400, "hh:mm:ss")
ThisWorkbook.Worksheets(2).Cells(1, 1) = secondsElapsed
End Sub
This opens a new instance for each file and closes it afterwards. Give it a try (I could not test it). This includes all the suggestions I made in the chat.
Option Explicit
Sub getCBU()
Dim location As String
location = "C:\Users\swallin\Documents\CBU History\"
Dim nextFile As String
nextFile = Dir(location & "CBU*")
Dim rowCount As Long
rowCount = 2
Dim startTime As Double
startTime = Timer
Dim newRow(1 To 17) As Variant, compareRow(1 To 17) As Variant
Dim lastRow As Long, match As Boolean
Dim s As Long, x As Long, y As Long, j As Long, v As Long, t As Long
Dim objExcel As Object, ActWb As Workbook
Do While nextFile <> ""
Set objExcel = CreateObject("Excel.Application") 'new excel instance
Set ActWb = objExcel.Workbooks.Open(Filename:=location & nextFile, ReadOnly:=True)
lastRow = ActWb.Worksheets(1).Cells(Rows.Count, 1).End(xlUp).Row
For s = 18 To lastRow
match = True
For x = 1 To 17
newRow(x) = ActWb.Worksheets(1).Cells(s, x)
Next x
For y = 2 To rowCount
If Val(newRow(11)) = Val(ThisWorkbook.Worksheets(1).Cells(y, 11)) Then
For j = 1 To 17
compareRow(j) = ThisWorkbook.Worksheets(1).Cells(y, j).Value
Next j
For v = 1 To 17
If Val(compareRow(v)) <> Val(newRow(v)) Then
match = False
Exit For
Else
match = True
End If
Next v
If match = True Then
Exit For
End If
Else
match = False
End If
Next y
y = 2
If match = False Then
rowCount = rowCount + 1
For t = 1 To 17
ThisWorkbook.Worksheets(1).Cells(rowCount, t) = newRow(t)
Next t
End If
Next s
s = 18
ActWb.Close SaveChanges:=False
objExcel.Quit 'close excel instance
Set objExcel = Nothing 'free variable
nextFile = Dir()
Loop
Dim secondsElapsed As String
secondsElapsed = Format$((Timer - startTime) / 86400, "hh:mm:ss")
ThisWorkbook.Worksheets(2).Cells(1, 1) = secondsElapsed
End Sub
Not sure about the writing back to the sheet part (i would still allocate the values to an array and write it back all together, but that depends on what you have in the sheet already, plus whatever newRow() does), but can you give this a try and see if there is any improvement in speed?
Sub getCBU()
Dim rowCount As Long, newRow(1 To 17) As Variant, compareRow(1 To 17) As Variant, nextFile As String
Dim location As String, lastRow As Long, match As Boolean, startTime As Double, secondsElapsed As String
Dim arrData, arrOutput()
Dim arrTemp(): ReDim arrOutput(1 To 17, 1 To 1)
Dim R As Long, C As Long
location = "C:\Users\swallin\Documents\CBU History\"
nextFile = Dir(location & "CBU*")
rowCount = 2
startTime = Timer
Do While nextFile <> ""
Workbooks.Open (location & nextFile)
lastRow = Workbooks(nextFile).Worksheets(1).Cells(Rows.Count, 1).End(xlUp).row
With Workbooks(nextFile).Worksheets(1)
arrData = .Range(.Cells(1, 1), .Cells(lastRow, 17))
End With
For s = 18 To lastRow
match = True
For X = 1 To 17
newRow(X) = arrData(s, X)
Next X
For y = 2 To rowCount
If Val(newRow(11)) = Val(arrData(y, 11)) Then
For j = 1 To 17
compareRow(j) = arrData(y, j).Value
Next j
For v = 1 To 17
If Val(compareRow(v)) <> Val(newRow(v)) Then
match = False
Exit For
Else
match = True
End If
Next v
If match = True Then
Exit For
End If
Else
match = False
End If
Next y
y = 2
If match = False Then
rowCount = rowCount + 1
ReDim Preserve arrTemp(1 To 17, 1 To rowCount)
For t = 1 To 17
arrTemp(t, rowCount) = newRow(t)
Next t
End If
Next s
s = 18
Workbooks(nextFile).Close
nextFile = Dir()
Loop
'Transpose the array
ReDim arrOutput(1 To UBound(arrTemp, 2), 1 To UBound(arrTemp))
For C = LBound(arrTemp) To UBound(arrTemp)
For R = LBound(arrTemp, 2) To UBound(arrTemp, 2)
arrOutput(R, C) = arrTemp(C, R)
Next R
Next C
'Allocate back to the spreadsheet
With ThisWorkbook.Worksheets(1)
.Range(.Cells(2, 1), .Cells(UBound(arrOutput) + 1, 17)) = arrOutput
End With
secondsElapsed = Format((Timer - startTime) / 86400, "hh:mm:ss")
ThisWorkbook.Worksheets(2).Cells(1, 1) = secondsElapsed
End Sub
PS: As others suggested, is a good idea to use Option Explicit, and eventually to step through to code and see if everything is working as intended.
As for the Overflow issue... stepping through code would/should resolve that as well eventually. See Overflow (Error 6) for more info.
EDIT: I've added further management to holding the values in an array, and writing back to the spreadsheet.
Here's a revamp of your code that should be quicker and more memory friendly. (updated to be able to handle any number of results).
Sub getCBU()
Dim wb As Workbook
Dim wsDest As Worksheet
Dim wsTime As Worksheet
Dim hUnqVals As Object
Dim hUnqRows As Object
Dim aHeaders() As Variant
Dim aCompare() As Variant
Dim aResults() As Variant
Dim aStartingData() As Variant
Dim sFolder As String
Dim sFile As String
Dim sDelim As String
Dim sTemp As String
Dim lMaxResults As Long
Dim lCompareStartRow As Long
Dim lValCompareCol As Long
Dim ixCompare As Long
Dim ixResult As Long
Dim ixCol As Long
Dim dTimer As Double
dTimer = Timer
Set wb = ThisWorkbook
Set wsDest = wb.Worksheets(1)
Set wsTime = wb.Worksheets(2)
Set hUnqRows = CreateObject("Scripting.Dictionary")
Set hUnqVals = CreateObject("Scripting.Dictionary")
sDelim = "|"
lMaxResults = 100000
lCompareStartRow = 18
lValCompareCol = 11
sFolder = Environ("UserProfile") & "\Documents\CBU History\" 'Be sure to including ending \
sFile = Dir(sFolder & "CBU*.xlsx")
With wsDest.Range("A2:Q" & wsDest.Cells(wsDest.Rows.Count, lValCompareCol).End(xlUp).Row)
If .Row > 1 Then
aHeaders = .Offset(-1).Resize(1).Value
aStartingData = .Value
ReDim aResults(1 To lMaxResults, 1 To .Columns.Count)
For ixResult = 1 To UBound(aStartingData, 1)
For ixCol = 1 To UBound(aStartingData, 2)
sTemp = sTemp & sDelim & aStartingData(ixResult, ixCol)
Next ixCol
If Not hUnqRows.Exists(sTemp) Then hUnqRows.Add sTemp, sTemp
If Not hUnqVals.Exists(aStartingData(ixResult, lValCompareCol)) Then hUnqVals.Add aStartingData(ixResult, lValCompareCol), aStartingData(ixResult, lValCompareCol)
sTemp = vbNullString
Next ixResult
Erase aStartingData
Else
'No data to compare against, so no data can be added, exit macro
MsgBox "No data found in [" & wsDest.Name & "]" & Chr(10) & "Exiting Macro.", , "Error"
Exit Sub
End If
End With
With Application
.Calculation = xlCalculationManual
.EnableEvents = False
.ScreenUpdating = False
End With
ixResult = 0
Do While Len(sFile) > 0
Application.StatusBar = "Processing " & sFile & "..."
With Workbooks.Open(sFolder & sFile, , True).Worksheets(1)
With .Range("A" & lCompareStartRow & ":Q" & .Cells(.Rows.Count, lValCompareCol).End(xlUp).Row)
If .Row >= lCompareStartRow Then
aCompare = .Value
For ixCompare = 1 To UBound(aCompare, 1)
If hUnqVals.Exists(aCompare(ixCompare, lValCompareCol)) Then
For ixCol = 1 To UBound(aCompare, 2)
sTemp = sTemp & sDelim & aCompare(ixCompare, ixCol)
Next ixCol
If Not hUnqRows.Exists(sTemp) Then
hUnqRows.Add sTemp, sTemp
ixResult = ixResult + 1
For ixCol = 1 To UBound(aCompare, 2)
aResults(ixResult, ixCol) = aCompare(ixCompare, ixCol)
Next ixCol
If ixResult = lMaxResults Then OutputResults wsDest, aResults, ixResult, aHeaders
End If
sTemp = vbNullString
End If
Next ixCompare
Erase aCompare
End If
End With
.Parent.Close False
End With
sFile = Dir()
Loop
Application.StatusBar = vbNullString
If ixResult > 0 Then OutputResults wsDest, aResults, ixResult, aHeaders
wsTime.Range("A1").Value = Format((Timer - dTimer) / 86400, "hh:mm:ss")
With Application
.Calculation = xlCalculationAutomatic
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
Sub OutputResults(ByRef arg_ws As Worksheet, ByRef arg_aResults As Variant, ByRef arg_ixResult As Long, ByVal arg_aHeaders As Variant)
Static wsDest As Worksheet
Dim rDest As Range
Dim lMaxRows As Long
Dim lMaxCols As Long
If wsDest Is Nothing Then Set wsDest = arg_ws
lMaxRows = UBound(arg_aResults, 1)
lMaxCols = UBound(arg_aResults, 2)
Set rDest = wsDest.Range("A1").Resize(, lMaxCols).EntireColumn.Find("*", wsDest.Range("A1"), xlValues, xlWhole, , xlPrevious)
If rDest Is Nothing Then Set rDest = wsDest.Range("A2") Else Set rDest = wsDest.Cells(rDest.Row, "A")
If rDest.Row + 1 + arg_ixResult > wsDest.Rows.Count Then
Set wsDest = wsDest.Parent.Worksheets.Add(After:=wsDest)
With wsDest.Range("A1").Resize(, lMaxCols)
.Value = arg_aHeaders
.Font.Bold = True
End With
Set rDest = wsDest.Range("A2")
End If
rDest.Resize(arg_ixResult, lMaxCols).Value = arg_aResults
Erase arg_aResults
ReDim arg_aResults(1 To lMaxRows, 1 To lMaxCols)
End Sub

Slow Excel VBA code

I have tried to write a code that will look at cells in B2 from Row 4 to R2000 and if the content is zero then hide the row. My problem is that the code is running very slow and often stops responding.
If you can help me what it is that is causing it to run slow, I can probably fix it myself, but I am not sure what would be a more efficient approach. As you can see I have tried with turning screen updates off, but it didn’t help much.
The code is below
Sub HideRows()
BeginRow = 4
EndRow = 2059
ChkCol = 2
Application.ScreenUpdating = False
Rows("1:2059").EntireRow.Hidden = False
For RowCnt = BeginRow To EndRow
If Cells(RowCnt, ChkCol).Value = 0 Then
Cells(RowCnt, ChkCol).EntireRow.Hidden = True
End If
Next RowCnt
Application.ScreenUpdating = True
End Sub
Try hiding everything in one go instead of every time a 0 is found
Sub HideRows()
Dim BeginRow As Long, EndRow As Long, ChkCol As Long
Dim HideRng As Range
BeginRow = 4
EndRow = 2059
ChkCol = 2
Application.ScreenUpdating = False
Rows("1:2059").EntireRow.Hidden = False
For rowcnt = BeginRow To EndRow
If Cells(rowcnt, ChkCol).Value2 = 0 Then
If HideRng Is Nothing Then
Set HideRng = Cells(rowcnt, ChkCol)
Else
HideRng = Union(HideRng, Cells(rowcnt, ChkCol))
End If
End If
Next rowcnt
If Not HideRng Is Nothing Then HideRng.EntireRow.Hidden = True
Application.ScreenUpdating = True
End Sub
Without seeing your workbook, it's hard to know for sure, but generally Excel is pretty slow at hiding rows. In your code, each row is hidden one at a time, so that's potentially 1000+ individual "hide this row" commands to Excel.
It's much faster to hide the rows in "chunks". This macro (I wrote it ages ago because I was dealing with the same problem) does that, so it should be much faster. In your case, you'd call it like this:
Call hideRows(ActiveSheet, 4, 2059, 0, 2, 2)
There's also an inverted setting that would hide rows unless the value in column 2 was equal to zero. You'd just add "True" to the end of your function call.
Sub hideRows(ws As Worksheet, startRow As Long, endRow As Long, valCrit As Variant, Optional startCol As Long = 1, Optional endCol As Long = 1, Optional invert As Boolean = False)
Dim loopCounter As Long
Dim rowCounter As Long
Dim colCounter As Long
Dim endConsRow As Long
Dim tempArr As Variant
Dim toAdd As Long
Dim toHide As String
Dim sameVal As Boolean
Dim consBool As Boolean
Dim tempBool As Boolean
Dim rowStr As String
Dim goAhead As Boolean
Dim i As Long
If startRow > endRow Then
toAdd = endRow - 1
Else
toAdd = startRow - 1
End If
tempArr = ws.Range(ws.Cells(startRow, startCol), ws.Cells(endRow, endCol)).Value
ws.Rows(startRow & ":" & endRow).Hidden = False
loopCounter = 1
For rowCounter = LBound(tempArr, 1) To UBound(tempArr, 1)
For colCounter = LBound(tempArr, 2) To UBound(tempArr, 2)
sameVal = False
goAhead = False
If IsNumeric(valCrit) Then
If tempArr(rowCounter, colCounter) = valCrit Then
sameVal = True
End If
Else
If tempArr(rowCounter, colCounter) Like valCrit Then
sameVal = True
End If
End If
If sameVal Then
If invert = True Then
loopCounter = loopCounter + 1
Exit For
End If
goAhead = True
ElseIf colCounter = UBound(tempArr, 2) Then
If invert = False Then
loopCounter = loopCounter + 1
Exit For
End If
goAhead = True
End If
If goAhead = True Then
endConsRow = rowCounter
consBool = True
Do Until consBool = False
tempBool = False
For i = LBound(tempArr, 2) To UBound(tempArr, 2)
sameVal = False
If endConsRow = UBound(tempArr, 1) Then
Exit For
ElseIf IsNumeric(valCrit) Then
If tempArr(endConsRow + 1, i) = valCrit Then
sameVal = True
End If
Else
If tempArr(endConsRow + 1, i) Like valCrit Then
sameVal = True
End If
End If
If sameVal Then
If invert = False Then
endConsRow = endConsRow + 1
tempBool = True
End If
Exit For
ElseIf i = UBound(tempArr, 2) Then
If invert = True Then
endConsRow = endConsRow + 1
tempBool = True
End If
End If
Next
If tempBool = False Then
consBool = False
End If
Loop
rowStr = loopCounter + toAdd & ":" & endConsRow + toAdd
If toHide = "" Then
toHide = rowStr
ElseIf Len(toHide & "," & rowStr) > 255 Then
ws.Range(toHide).EntireRow.Hidden = True
toHide = rowStr
Else
toHide = toHide & "," & rowStr
End If
loopCounter = loopCounter + 1 + (endConsRow - rowCounter)
rowCounter = endConsRow
Exit For
End If
Next
Next
If Not toHide = "" Then
ws.Range(toHide).EntireRow.Hidden = True
End If
End Sub
Can you use Autofilter?
Option Explicit
Public Sub HideRowsWhereColBis0()
ActiveSheet.Range("B4:B2059").AutoFilter Field:=1, Criteria1:="<>0"
End Sub

VB - Import CSV in excel with end line in same cell

Ok, this gonna be long.
I have a csv file that I want to import in a excel.
This is the CSV file.
"NIP";"Date start";"Date end";"Reason";"coment"
"1";"06/06/17 09:55";"";"test";"asdasd ad ,a dasds asd;asdfasfasdfad ,
asdfasdfda a
asffasd , asdf asf asfad; asfasfasfa ;sadfdasds
,adasdsa ,asdassda,adadasddasd, asd asdasdad
;;;;adasdasdsa ,,,,sfdafas"
This is how looks on excel.
When this CSV is imported on excel using VB (the excel will import a lot of csv files), this is how it looks.
This is my VB code to import CSV
Option Explicit
Sub ImportFiles()
Dim sPath As String
sPath = ThisWorkbook.Path & "\data\1.csv"
'copyDataFromCsvFileToSheet sPath, ";", "1"
sPath = ThisWorkbook.Path & "\data\2.csv"
'copyDataFromCsvFileToSheet sPath, ";", "2"
sPath = ThisWorkbook.Path & "\data\3.csv"
'copyDataFromCsvFileToSheet sPath, ";", "3"
sPath = ThisWorkbook.Path & "\data\4.csv"
'copyDataFromCsvFileToSheet sPath, ";", "4"
sPath = ThisWorkbook.Path & "\data\5.csv"
'copyDataFromCsvFileToSheet sPath, ";", "5"
sPath = ThisWorkbook.Path & "\data\6.csv"
'copyDataFromCsvFileToSheet sPath, ";", "6"
sPath = ThisWorkbook.Path & "\data\7.csv"
'copyDataFromCsvFileToSheet sPath, ";", "7"
sPath = ThisWorkbook.Path & "\data\8.csv"
'copyDataFromCsvFileToSheet sPath, ";", "8"
sPath = ThisWorkbook.Path & "\data\9.csv"
'copyDataFromCsvFileToSheet sPath, ";", "9"
sPath = ThisWorkbook.Path & "\data\10.csv"
'copyDataFromCsvFileToSheet sPath, ";", "10"
sPath = ThisWorkbook.Path & "\data\11.csv"
'copyDataFromCsvFileToSheet sPath, ";", "11"
sPath = ThisWorkbook.Path & "\data\12.csv"
copyDataFromCsvFileToSheet sPath, ";", "12"
sPath = ThisWorkbook.Path & "\data\13.csv"
'copyDataFromCsvFileToSheet sPath, ";", "13"
Dim aux As String
aux = FindReplaceAll()
End Sub
Private Sub copyDataFromCsvFileToSheet(parFileName As String, _
parDelimiter As String, parSheetName As String)
Dim Data As Variant
Data = getDataFromFile(parFileName, parDelimiter)
If Not isArrayEmpty(Data) Then
If SheetExists(parSheetName) Then
With Sheets(parSheetName)
.Range("A1:OO2000").ClearContents
.Cells(1, 1).Resize(UBound(Data, 1), UBound(Data, 2)) = Data
End With
Else
Dim warning
warning = MsgBox("no existing sheet'" & parSheetName, vbOKOnly, "Warning")
End If
End If
End Sub
Function SheetExists(shtName As String, Optional wb As Workbook) As Boolean
Dim sht As Worksheet
If wb Is Nothing Then Set wb = ThisWorkbook
On Error Resume Next
Set sht = wb.Sheets(shtName)
On Error GoTo 0
SheetExists = Not sht Is Nothing
End Function
Function FindReplaceAll()
Dim sht As Worksheet
Dim fnd As Variant
Dim rplc As Variant
For Each sht In ActiveWorkbook.Worksheets
sht.Cells.Replace what:=Chr(34), Replacement:="", _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
Next sht
End Function
Public Function isArrayEmpty(parArray As Variant) As Boolean
If IsArray(parArray) = False Then isArrayEmpty = True
On Error Resume Next
If UBound(parArray) < LBound(parArray) Then
isArrayEmpty = True
Exit Function
Else
isArrayEmpty = False
End If
End Function
Private Function getDataFromFile(parFileName As String, _
parDelimiter As String, _
Optional parExcludeCharacter As String = "") As Variant
Dim locLinesList() As Variant
Dim locData As Variant
Dim i As Long
Dim j As Long
Dim lim As Long
Dim locNumRows As Long
Dim locNumCols As Long
Dim fso As Variant
Dim ts As Variant
Const REDIM_STEP = 10000
Set fso = CreateObject("Scripting.FileSystemObject")
On Error GoTo error_open_file
Set ts = fso.OpenTextFile(parFileName)
On Error GoTo unhandled_error
ReDim locLinesList(1 To 1) As Variant
i = 0
Do While Not ts.AtEndOfStream
Dim aux As String
aux = ts.ReadLine
If i Mod REDIM_STEP = 0 Then
ReDim Preserve locLinesList _
(1 To UBound(locLinesList, 1) + REDIM_STEP) As Variant
lim = UBound(Split(aux, parDelimiter)) + 1
End If
locLinesList(i + 1) = Split(aux, """+parDelimiter+""")
j = UBound(locLinesList(i + 1), 1)
If locNumCols < j Then locNumCols = j
i = i + 1
Loop
ts.Close
locNumRows = i
If locNumRows = 0 Then Exit Function
ReDim locData(1 To locNumRows, 1 To locNumCols + 1) As Variant
If parExcludeCharacter <> "" Then
For i = 1 To locNumRows
For j = 0 To UBound(locLinesList(i), 1)
If Left(locLinesList(i)(j), 1) = parExcludeCharacter Then
If Right(locLinesList(i)(j), 1) = parExcludeCharacter Then
locLinesList(i)(j) = _
Mid(locLinesList(i)(j), 2, Len(locLinesList(i)(j)) - 2)
Else
locLinesList(i)(j) = _
Right(locLinesList(i)(j), Len(locLinesList(i)(j)) - 1)
End If
ElseIf Right(locLinesList(i)(j), 1) = parExcludeCharacter Then
locLinesList(i)(j) = _
Left(locLinesList(i)(j), Len(locLinesList(i)(j)) - 1)
End If
locData(i, j + 1) = locLinesList(i)(j)
Next j
Next i
Else
For i = 1 To locNumRows
For j = 0 To UBound(locLinesList(i), 1)
locData(i, j + 1) = locLinesList(i)(j)
Next j
Next i
End If
getDataFromFile = locData
Exit Function
error_open_file:
unhandled_error:
End Function
I want that in the excel to look like when you open the csv in excel.
This was my solution.
First I added two new functions.
Public Function mergeArrays(arr1 As Variant, arr2 As Variant) As Variant
Dim i As Integer
Dim sizeArr1 As Integer
Dim arr3() As String
ReDim arr3(UBound(arr1) + UBound(arr2) + 1)
sizeArr1 = UBound(arr1) + 1
For i = 0 To UBound(arr1)
arr3(i) = arr1(i)
Next i
For i = 0 To UBound(arr2)
arr3(i + sizeArr1) = arr2(i)
Next i
mergeArrays = arr3
End Function
Public Function DeleteElementAt(inArray As Variant) As Variant
Dim index As Integer
Dim aux() As String
ReDim aux(UBound(inArray) - 1)
For index = 1 To UBound(inArray)
aux(index - 1) = inArray(index)
Next index
DeleteElementAt = aux
End Function
Also I modified getDataFromFile
Private Function getDataFromFile(parFileName As String, _
parDelimiter As String, _
Optional parExcludeCharacter As String = "") As Variant
Dim locLinesList() As Variant
Dim locData As Variant
Dim linea() As String
Dim i As Long
Dim j As Long
Dim lim As Long
Dim locNumRows As Long
Dim locNumCols As Long
Dim fso As Variant
Dim ts As Variant
Const REDIM_STEP = 10000
Set fso = CreateObject("Scripting.FileSystemObject")
On Error GoTo error_open_file
Set ts = fso.OpenTextFile(parFileName)
On Error GoTo unhandled_error
ReDim locLinesList(1 To 1) As Variant
i = 0
Do While Not ts.AtEndOfStream
Dim aux As String
aux = ts.ReadLine
aux = Replace(aux, Chr(34) & ";" & Chr(34), Chr(34) & "###" & Chr(34))
linea = Split(aux, "###")
If i Mod REDIM_STEP = 0 Then
ReDim Preserve locLinesList _
(1 To UBound(locLinesList, 1) + REDIM_STEP) As Variant
lim = UBound(linea) + 1
locNumCols = lim
locLinesList(i + 1) = linea
i = i + 1
Else
locLinesList(i + 1) = linea
If UBound(locLinesList(i)) + 1 < lim Then
locLinesList(i)(UBound(locLinesList(i))) = locLinesList(i)
(UBound(locLinesList(i))) & vbCrLf & linea(0)
linea = DeleteElementAt(linea)
locLinesList(i) = mergeArrays(locLinesList(i), linea)
Else
If UBound(linea) + 1 = 1 Then
locLinesList(i)(UBound(locLinesList(i))) = locLinesList(i)
(UBound(locLinesList(i))) & vbCrLf & linea(0)
Else
'Linea es un salto de linea a secas
If UBound(linea) = -1 Then
locLinesList(i)(UBound(locLinesList(i))) = locLinesList(i)
(UBound(locLinesList(i))) & vbCrLf
Else
i = i + 1
End If
End If
End If
End If
Loop
Dim endVector() As Variant
ReDim endVector(i)
Dim index As Integer
For index = 0 To i - 1
endVector(index) = locLinesList(index + 1)
Next index
ts.Close
locNumRows = i
If locNumRows = 0 Then Exit Function
ReDim locData(1 To locNumRows, 1 To locNumCols) As Variant
If parExcludeCharacter <> "" Then
For i = 1 To locNumRows
For j = 0 To UBound(endVector(i), 1)
If Left(endVector(i)(j), 1) = parExcludeCharacter Then
If Right(endVector(i)(j), 1) = parExcludeCharacter Then
endVector(i)(j) = _
Mid(endVector(i)(j), 2, Len(endVector(i)(j)) - 2)
Else
endVector(i)(j) = _
Right(endVector(i)(j), Len(endVector(i)(j)) - 1)
End If
ElseIf Right(endVector(i)(j), 1) = parExcludeCharacter Then
endVector(i)(j) = _
Left(endVector(i)(j), Len(endVector(i)(j)) - 1)
End If
locData(i, j + 1) = endVector(i)(j)
Next j
Next i
Else
For i = 0 To locNumRows - 1
For j = 0 To UBound(endVector(i), 1)
locData(i + 1, j + 1) = endVector(i)(j)
Next j
Next i
End If
getDataFromFile = locData
Exit Function
I know that this code can optimized but for now It works

How to exit for loop in excel-vba

My dataset is like this
I want to make them
Please look at the first row.
My code is
Private Sub CommandButton1_Click()
Dim MyColInstance, i As Long
Dim MyWorksheetLastColumn As Byte
MyWorksheetLastColumn = Worksheets(1).Cells(1, columns.Count).End(xlToLeft).Column
For i = 1 To MyWorksheetLastColumn
MyColInstance = ColInstance("Preference", i)
Cells(1, MyColInstance).Value = "Preference" & i
Next i
End Sub
Function ColInstance(HeadingString As String, InstanceNum As Long)
Dim ColNum As Long
On Error Resume Next
ColNum = 0
For X = 1 To InstanceNum
ColNum = (Range("A1").Offset(0, ColNum).Column) + Application.WorksheetFunction.Match(HeadingString, Range("A1").Offset(0, ColNum + 1).Resize(1, Columns.Count - (ColNum + 1)), 0)
Next
ColInstance = ColNum
End Function
The problem is while running this code, it shows an error because the for loop is not complete. What can we do?
Can you do it this way? It seems to me you are just adding a suffix to your headers in the first row...
Sub UpdateColumnHeaders()
Dim headers As Range, header As Range, suffixes As Range, suffix As Range, i As Integer
Set headers = Range(Cells(1, 1), Cells(1, Range("A1").End(xlToRight).Column))
Set suffixes = Range("A1:A" & Range("A1").End(xlDown).Row)
i = 1
For Each header In headers
If header = "Preferences" Then
header = header & suffixes(i)
i = i + 1
End If
Next
End Sub
Private Sub CommandButton1_Click()
Dim Count1, Count2 As Integer
Dim MyWorksheetLastRow As Byte
Dim MyColInstance, emp_i As Long
For Each Row_Cel In Range("1:1")
If Row_Cel.Value = "Employment" Then
Count1 = Count1 + 1
End If
If Row_Cel.Value = "Job" Then
Count2 = Count2 + 1
End If
Next Row_Cel
For emp_i = 1 To Count1
MyColInstance = ColInstance("Employment", emp_i)
Cells(1, MyColInstance).Value = "Employment" & emp_i
Next emp_i
For emp_i = 1 To Count2
MyColInstance = ColInstance("Job", emp_i)
Cells(1, MyColInstance).Value = "Job" & emp_i
Next emp_i
End Sub
Function ColInstance(HeadingString As String, InstanceNum As Long)
Dim ColNum As Long
On Error Resume Next
ColNum = 0
For X = 1 To InstanceNum
ColNum = (Range("A1").Offset(0, ColNum).Column) + Application.WorksheetFunction.Match(HeadingString, Range("A1").Offset(0, ColNum + 1).Resize(1, Columns.Count - (ColNum + 1)), 0)
Next
ColInstance = ColNum
End Function

Resources