Here is my code:
Private Sub UserForm_Initialize()
Dim MyFolder As String
Dim MyFile As String
Dim j As Integer
Dim Funds(1000)
CD_Date = Cells(1, 4)
Range("A2").Select
i = 1
Do
Funds(i) = UCase(ActiveCell.Value)
i = i + 1
ActiveCell.Offset(1, 0).Select
Loop Until ActiveCell.Value = ""
MyFolder = "C:\windows\"
r = 0
For k = 1 To i - 1
MyFile = Dir$(MyFolder & "*" & Funds(k) & "*")
Do While MyFile <> ""
datka = FileDateTime(MyFolder & MyFile)
If Format(datka, "yymmdd") = Format(CD_Date, "yymmdd") Then
With UserForm1.ListBox1
.AddItem
.List(r, 0) = Funds(k)
.List(r, 1) = MyFile
r = r + 1
End With
End If
MyFile = Dir$
Loop
Next k
Range("A2").Select
End Sub
Code works perfectly, but it doesn't change dynamically when I move CD_Date for prior day or current - 2. It always add item for entered date and only for first run. When I change date in cell it always return me list from first initialize. It resets when I close file and open it again, each time for different date. Is it possible to modify my code that it will be filling dynamically after I change CD_Date or when someone add file to the folder?? I want to avoid closing and opening macro over and over just to get actual data :(
You could add in a loop to remove all items from the ListBox before the point in your code where items are added to effectively refresh it each time. To do this you are looking for something like:
With UserForm1.ListBox1
For i = 1 to .ListCount
.RemoveItem(0)
Next i
End With
In your code it seems like each time you open the form you only want one item in the ListBox, so although the loop here is unnecessary its a good practice to remember. Try placing this in your module just before you add the item:
Private Sub UserForm_Initialize()
Dim MyFolder As String
Dim MyFile As String
Dim j As Integer
Dim Funds(1000)
CD_Date = Cells(1, 4)
Range("A2").Select
i = 1
Do
Funds(i) = UCase(ActiveCell.Value)
i = i + 1
ActiveCell.Offset(1, 0).Select
Loop Until ActiveCell.Value = ""
MyFolder = "C:\windows\"
r = 0
For k = 1 To i - 1
MyFile = Dir$(MyFolder & "*" & Funds(k) & "*")
Do While MyFile <> ""
datka = FileDateTime(MyFolder & MyFile)
If Format(datka, "yymmdd") = Format(CD_Date, "yymmdd") Then
With UserForm1.ListBox1
For i = 1 to .ListCount 'Here
.RemoveItem(0)
Next i
.AddItem
.List(r, 0) = Funds(k)
.List(r, 1) = MyFile
r = r + 1
End With
End If
MyFile = Dir$
Loop
Next k
Range("A2").Select
End Sub
Related
I am trying to copy a specific cell and 3 columns from multiple files into a single column on another spreadsheet.
The part called "import" simply allows to select multiple files. The part "Datacopy" should copy the desired values.
Sub import()
Dim oFileDialog As FileDialog
Set oFileDialog = Application.FileDialog(msoFileDialogFilePicker)
oFileDialog.AllowMultiSelect = True
oFileDialog.InitialFileName = "C:\Users\L18938\Desktop\New_folder" ' can set your default directory here
oFileDialog.Show
Dim iCount As Integer
For iCount = 1 To oFileDialog.SelectedItems.Count
Call Datacopy(oFileDialog.SelectedItems(iCount))
Next
End Sub
Public Function Datacopy(strPath As String)
Dim filePath As String
Dim FileNum As Integer
filePath = strPath
Dim startDate As String
If Range("A2").Value <> "" Then
Range("A1").End(xlDown).Offset(1, 0).Select
Else:
Range("A1:A" & Range("A" & Rows.Count).End(xlUp).Row).Offset(1, 0).Select
End If
currentRow = 0
rowNumber = 0
Open filePath For Input As #1
'EOF(1) checks for the end of a file
Do Until EOF(1)
If rowNumber = 0 Then
startDate = lineitems(2)
End If
If rowNumber > 18 And item <> "" Then
ActiveCell.Offset(currentRow, 0) = startDate
ActiveCell.Offset(currentRow, 1) = lineitems(0)
ActiveCell.Offset(currentRow, 2) = lineitems(1)
ActiveCell.Offset(currentRow, 3) = lineitems(2)
currentRow = currentRow + 1
End If
End If
Next item
rowNumber = rowNumber + 1
Loop
Close #1
End Function
When I run it I get the error "sub or function not defined".
The cells I am targeting are:
C1 -> is a date, different in each file, to be copied in column A
Columns A18:A, B18:B, C18:C -> are data to be copied in columns B, C, D respectively.
It is important to copy multiple files, as I have more than 180.
Your problem is "startDate = lineitems(2)". There's nothing in your code that assigns any kind of value to "lineitems".
I want to import multiple csv files at the bottom of an existing table. However, when importing the files, it always excludes the first row of the list of each file. The first row of the list differs from the first row of the spreadsheet because in between there are other rows that are not needed (e.g. titles, empty rows...). Resuming: if I upload 5 files, it miss the first desired row of each of the 5 files.
This is the code:
Private Sub Import_auction_offers_Click()
Dim strSourcePath As String
Dim strFile As String
Dim Cnt As Long
'Change the path to the source folder accordingly
strSourcePath = "C:\Users\L18944\Desktop\example"
If Right(strSourcePath, 1) <> "\" Then strSourcePath = strSourcePath & "\"
strFile = Dir(strSourcePath & "*.csv")
Do While Len(strFile) > 0
Cnt = Cnt + 1
Open strSourcePath & strFile For Input As #1
If Range("F2").Value <> "" Then
Range("F1").End(xlDown).offset(1, 0).Select
Else:
Range("F1:F" & Range("F" & Rows.Count).End(xlUp).Row).offset(1, 0).Select
End If
currentRow = 0
rowNumber = 0
'EOF(1) checks for the end of a file
Do Until EOF(1)
Line Input #1, lineFromFile
fileStr = Split(lineFromFile, vbLf)
Dim item As Variant
For Each item In fileStr
'For item = LBound(fileStr) To UBound(fileStr)
lineitems = Split(item, ";")
'Debug.Print (item)
If rowNumber = 1 Then
startDate = lineitems(6)
End If
If rowNumber > 3 And item <> "" Then
If Not doesOfferExist(CStr(lineitems(2))) Then
ActiveCell.offset(currentRow, 0) = startDate
ActiveCell.offset(currentRow, 1) = lineitems(4)
ActiveCell.offset(currentRow, 2) = lineitems(3)
ActiveCell.offset(currentRow, 3) = CDbl(lineitems(6))
ActiveCell.offset(currentRow, 4) = CDbl(lineitems(7))
ActiveCell.offset(currentRow, 5) = lineitems(8)
ActiveCell.offset(currentRow, 6) = lineitems(1)
ActiveCell.offset(currentRow, 7) = lineitems(2)
ActiveCell.offset(currentRow, 8) = "New"
currentRow = currentRow + 1
End If
End If
rowNumber = rowNumber + 1
Next item
Loop
Close #1
Name strSourcePath & strFile As strSourcePath & strFile
strFile = Dir
Loop
Application.ScreenUpdating = True
If Cnt = 0 Then _
MsgBox "No CSV files were found...", vbExclamation
End Sub
Does anyone understand why it miss the first line of each imported list?
Thank you in advance
I didn't go through your ImportAuctionOffers code, but I'm assuming you are finding the new starting row for each file.
This code will let you pick your files (and set your initial directory). Then loop through all the selected items, calling your ImportAuctionOffers procedure for each file.
Sub test()
Dim oFileDialog As FileDialog
Set oFileDialog = Application.FileDialog(msoFileDialogFilePicker)
oFileDialog.AllowMultiSelect = True
oFileDialog.InitialFileName = "C:\Temp" ' can set your default directory here
oFileDialog.Show
Dim iCount As Integer
For iCount = 1 To oFileDialog.SelectedItems.Count
Call ImportAuctionOffers(oFileDialog.SelectedItems(iCount))
Next
End Sub
Update:
For your second issue: Not reading the first data line is likely due to the if statements with RowNumber.
rowNumber=0
Do ...
if RowNumber = 1 Then ...
if RowNumber > 3 ...
RowNumber = RowNumber + 1
loop
Your code is not going to enter either of your if statements when RowNumber equals 0, 2, or 3. You probably just need to change your > 3 to either > 2, or >= 3.
I have the following excel spreadsheet, tracker.xls with 2 columns: category and count.
I want to loop through a subdirectory which contains pdf files which match the category column in my spreadsheet.
This is what I've done so far, but my code does not seem to be working:
Sub CV()
Function CVCount()
CategoryArray = Range("A2:A3")
CountArray = Range("B2:B3")
For i = 1 To UBound(CategoryArray)
For j = 1 To UBound(CategoryArray, 2)
'get name of category
Dim Category As String
Category = (myarray(i, j))
FolderPath = Category + "\"
path = FolderPath & "\*.pdf"
Filename = Dir(path)
For k = 1 To UBound(CountArray)
For l = 1 To UBound(CountArray, 2)
'get count
Do While Filename <> ""
count = count + 1
Filename = Dir()
Loop
'assign count to cell
Range("").Value = count
Next k
Next j
Next i
End Function
End Sub
I can't seem to figure out how to assign a count to a cell. Any ideas how to?
You're on the right track, but it's far simpler than that:
Option Explicit
Private Const baseFolder As String = "C:\Users\Hazel\Documents\Personal\Accounts\Childcare\"
Sub countFiles()
Dim path As String
Dim fileName As Variant
Dim count As Integer
Dim i As Integer
i = 1
Do While Range("A" & i + 1).Value <> ""
count = 0
i = i + 1
path = baseFolder & Range("A" & i).Value & "\"
fileName = Dir(path)
Do While fileName <> ""
If UCase$(Right(fileName, 3)) = "PDF" Then count = count + 1
fileName = Dir()
Loop
Range("B" & i).Value = count
Loop
End Sub
Just change the "baseFolder" constant to match your starting directory.
IO want to check all the edf files at the path main directory/ABC*/Y/XY*/*.edf and then check the files for a specific phrase and if found check for another phrase and so on and then fill the data in the spreadsheet. I have tried to achieve this through three methods but was stuck at some point in every method. Is it possible for anyone of you to go through the code and tell me where I am wrong and which the best approach if any. As the misconception created by my previous questions I don't want anyone to write code for me. I've started working on vba for three days and I've 5 days to complete this project. That's why I'd be grateful if anyone could have a look and tell me where I'm going wrong.
Approach 1 through simple directory command
In this First loop for FCS* is working great but then the second loop doesn't work at all and gives run-time error at the first iteration. I know this is not a good approach but in case any other doesn't work.
Sub Iterate_Folders()
Dim ctr As Integer
Dim ctr1 As Integer
ctr = 1
ctr1 = 1
Paths = "C:\Users\sobiakanwal\Downloads\QSHWRA\QSHWRA\ " ' Path should always contain a '\' at end
FirstDir = Dir(Paths, vbDirectory) ' Retrieving the first entry.
Do Until FirstDir = "" ' Start the loop.
If (FirstDir Like "FCS*") Then
ActiveSheet.Cells(ctr, 15).Value = Paths & FirstDir
Path1 = Paths & FirstDir & "\FUNCTION_BLOCK\DR*"
ActiveSheet.Cells(ctr, 20).Value = Path1
'ActiveSheet.Cells(ctr, 25).Value = SecondDir
SecondDir = Dir(Path1, vbDirectory)
Do While SecondDir = ""
ActiveSheet.Cells(ctr, 30).Value = "Hi"
If (True) Then
ctr1 = ctr1 + 1
End If
SecondDir = Dir()
Loop
ctr = ctr + 1
Else
End If
FirstDir = Dir() ' Getting next entry.
Loop
MsgBox (ctr1)
End Sub
Approach 2 through Recursion
I found the basic code for this in a tutorial and then edited it somewhat to my advantage. This doesn't work generically but gives the right answer in somewhat hard-coded manner. But I want you to check just the point where I'm stuck in the recursion function where I need to add the file handling code.
Public temp() As String
Public Count As Integer
Function ListFiles(FolderPath As String)
Dim myFile As String, text As String, textline As String, posLat As Integer, posLong As Integer
Dim k As Long, i As Long
ReDim temp(2, 0)
Count = 1
If Right(FolderPath, 1) <> "\" Then
FolderPath = FolderPath & "\"
End If
Recursive FolderPath
k = Range(Application.Caller.Address).Rows.Count
If k < UBound(temp, 2) Then
MsgBox "There are more rows, extend user defined function"
Else
For i = UBound(temp, 2) To k
ReDim Preserve temp(UBound(temp, 1), i)
temp(0, i) = ""
temp(1, i) = ""
temp(2, i) = ""
Next i
End If
ListFiles = Application.Transpose(temp)
ReDim temp(0)
End Function
Function Recursive(FolderPath As String)
Dim strFilename As String
Dim strFileContent As String
Dim iFile As Integer
Dim fileName As String, textData As String, textRow As String, fileNo As Integer
Dim Value As String, Folders() As String
Dim Folder As Variant, a As Long
Dim Right_FolderPath As String
ReDim Folders(0)
If Right(FolderPath, 2) = "\\" Then Exit Function
Value = Dir(FolderPath, &H10)
Do Until Value = ""
If Value = "." Or Value = ".." Then
Else
If GetAttr(FolderPath & Value) = 16 Then
Folders(UBound(Folders)) = Value
ReDim Preserve Folders(UBound(Folders) + 1)
Else
If Right(Value, 4) = ".edf" Then
If Count = 4 Then
Right_FolderPath = Right(FolderPath, 7)
If Left(Right_FolderPath, 2) = "DR" Then
strFilename = FolderPath & Value
iFile = FreeFile
Open strFilename For Input As #iFile
strFileContent = Input(LOF(iFile), iFile)
Close #iFile
If InStr(1, strFileContent, "hihowareyou") <> 0 Then
ActiveSheet.Cells(1, 1) = strFilename
longLoc = InStr(1, strFileContent, "Longitude:")
If longLoc <> 0 Then
ActiveSheet.Cells(1, 2) = Mid(strFleContent, longLoc + Len("Longitude:"), 10)
End If
End If
''''Here it goes all wrong
'myFile = FolderPath & Value
'myFile = Application.GetOpenFilename()
'fileNo = FreeFile 'Get first free file number
'Open fileName For Input As #fileNo
'Do While Not EOF(fileNo)
' Line Input #fileNo, textRow
' textData = textData & textRow
'Loop
'Close #fileNo
'posLat = InStr(text, "ff-ai")
'If Not posLat = vbNullString Then
' temp(0, UBound(temp, 2)) = Value
'End If
temp(0, UBound(temp, 2)) = FolderPath
temp(1, UBound(temp, 2)) = Value
temp(2, UBound(temp, 2)) = Count ' FileLen(FolderPath & Value)
ReDim Preserve temp(UBound(temp, 1), UBound(temp, 2) + 1)
End If
End If
End If
End If
End If
Value = Dir
Loop
For Each Folder In Folders
Count = Count + 1
Recursive FolderPath & Folder & "\"
Count = Count - 1
Next Folder
End Function
The Third Approach By Dictionary Object
This was suggested by someone on Stock Overflow and worked right for him but not for me. I don't know vba enough to debug it.
Sub build_FolderLevels(dFMs As Scripting.Dictionary, _
Optional sFM As String = "", _
Optional iFLDR As Long = 0)
Dim d As Long, fp As String, vFMs As Variant
If CBool(dFMs.Count) Then
vFMs = dFMs.Keys
For d = LBound(vFMs) To UBound(vFMs)
vFMs(d) = vFMs(d)
Next d
Else
vFMs = Array(sFM)
End If
dFMs.RemoveAll
For d = LBound(vFMs) To UBound(vFMs)
fp = Dir(vFMs(d), iFLDR)
Do While CBool(Len(fp))
dFMs.Add Key:=Left(vFMs(d), InStrRev(vFMs(d), Chr(92))) & fp, _
Item:=iFLDR
fp = Dir
Loop
Next d
End Sub
Sub main()
Dim fm As Long, sFM As String, vFMs As Variant, sMASK As String
Dim fn As Variant, dFNs As New Scripting.Dictionary
sFM = Environ("TMP") & "\QSHWRA\FCS*\FUNCTION_BLOCK\DR*\*.edf"
If UBound(Split(sFM, Chr(42))) < 2 Then Exit Sub '<~~possibly adjust this safety
sFM = Replace(sFM, "/", "\")
vFMs = Split(sFM, Chr(92))
sMASK = vFMs(LBound(vFMs))
For fm = LBound(vFMs) + 1 To UBound(vFMs)
sMASK = Join(Array(sMASK, vFMs(fm)), Chr(92))
If CBool(InStr(1, vFMs(fm), Chr(42))) Or fm = UBound(vFMs) Then
build_FolderLevels dFNs, sFM:=sMASK, iFLDR:=Abs((fm < UBound(vFMs)) * vbDirectory)
sMASK = vbNullString
End If
Next fm
'list the files
For Each fn In dFNs
Debug.Print "from dict: " & fn
Next fn
dFNs.RemoveAll: Set dFNs = Nothing
End Sub
I would suggest you go through all the subfolders below main directory, and just collect the files that meet your criteria. I'd probably use the WindowsShell with something like Dir MainFolder\*.edf /B /S (bare format and recursion switches set) and just save or collect those files that are in desired subfolders. But you could also do something similar with DIR or the FileSystemObject and recursion.
I have been working in this project step by step. I can't understand why it is not copying the row string values from the "SheetName" used as argument being passed into this function(SheetName). The function can read a file and create a second file with checkboxes based on the number of column titles found in the first file, but the column titles are not being copied into the second file as captions for the checkboxes. Any help is appreciated.
Function CallFunction(SheetName As Variant) As Long
Dim text As String
Dim titles(200) As String ' Dim titles(200) As String ' Array
Dim nTitles As Integer
Dim wks As Worksheet
Dim myCaption As String
Dim NewBook As Workbook
PathName = Range("F22").Value
Filename = Range("F23").Value
ControlFile = ActiveWorkbook.Name
Workbooks.Open Filename:=PathName & "\" & Filename
Set wks = ActiveWorkbook.Worksheets(SheetName)
For i = 1 To 199
If Trim(wks.Cells(4, i).Value) = "" Then
nTitles = i - 1
Exit For
End If
titles(i - 1) = wks.Cells(4, i).Value
Next
i = 1
Workbooks.Add
Set NewBook = ActiveWorkbook
NewBook.SaveAs fileExported
Workbooks.Open (fileExported)
For Each cell In Range(Sheets(SheetName).Cells(4, 1), Sheets(SheetName).Cells(4, 1 + nTitles))
myCaption = Sheets(SheetName).Cells(4, i).Value
With Sheets(SheetName).checkBoxes.Add(cell.Left, _
cell.Top, cell.Width, cell.Height)
.Interior.ColorIndex = 12
.Caption = myCaption
.Characters.text = myCaption
.Border.Weight = xlThin
.Name = myCaption
End With
i = i + 1
Next
End Function
I found the answer to my own question I just forgot to add the answer here. Ok, here it is
' Save all Jira column titles into jTitles
If sj = True Or ji = True Then
For j = 1 To 199
If Trim(wks1.Cells(4, j).Value) = "" Then
titlesj = j - 1
Exit For
End If
jTitles(j - 1) = wks1.Cells(4, j).Value
Next
j = 1
' Add column titles as checkboxes
For j = 0 To titlesj
Sheet1.ListBox1.AddItem jTitles(j)
Sheet1.ListBox3.AddItem jTitles(j)
Next
wb1.Close
End If