I am trying to make a tool that takes a data file that is pulled from a website and pushes that data to SQL server.
My existing structure uses VBA to navigate to the website, pull, and polish the file. Then it opens Access which imports the data to SQL Server, which has a series of VBA based reporting tools pointed to it.
I want to cut out the Access part of it and just send an update query from the VBA to the Server.
The source file is 104 columns. I have made the new tool that goes to the website, pulls the file, moves the data to the tool's workbook and transforms it.
Here is the code I put together to build the update query:
SQL = "Insert Into datafile(" & HVal1 & "," & HVal2 & "," & HVal3 & "," & HVal4 & "," & HVal5 & "," & HVal6 & "," & HVal7 & "," & HVal8 & "," & HVal9 & "," & HVal10 & "," & HVal11 & "," & HVal12 & "," & HVal13 & "," & HVal14 & "," & HVal15 & "," & HVal16 & "," & HVal17 & "," & HVal18 & "," & HVal19 & "," & HVal20 & "," & HVal21 & "," & HVal22 & "," & HVal23 & "," & HVal24 & "," & HVal25 & "," & HVal26 & "," & HVal27 & "," & HVal28 & "," & HVal29 & "," & HVal30 & "," & HVal31 & "," & HVal32 & "," & HVal33 & "," & HVal34 & "," & HVal35 & "," & HVal36 & "," & HVal37 & "," & HVal38 & "," & HVal39 & "," & HVal40 & "," & HVal41 & "," & HVal42 & "," & HVal43 & "," & HVal44 & "," & HVal45 & "," & HVal46 & "," & HVal47 & "," & HVal48 & "," & HVal49 & "," & HVal50 & "," & _
HVal51 & "," & HVal52 & "," & HVal53 & "," & HVal54 & "," & HVal55 & "," & HVal56 & "," & HVal57 & "," & HVal58 & "," & HVal59 & "," & HVal60 & "," & HVal61 & "," & HVal62 & "," & HVal63 & "," & HVal64 & "," & HVal65 & "," & HVal66 & "," & HVal67 & "," & HVal68 & "," & HVal69 & "," & HVal70 & "," & HVal71 & "," & HVal72 & "," & HVal73 & "," & HVal74 & "," & HVal75 & "," & HVal76 & "," & HVal77 & "," & HVal78 & "," & HVal79 & "," & HVal80 & "," & HVal81 & "," & HVal82 & "," & HVal83 & "," & HVal84 & "," & HVal85 & "," & HVal86 & "," & HVal87 & "," & HVal88 & "," & HVal89 & "," & HVal90 & "," & HVal91 & "," & HVal92 & "," & HVal93 & "," & HVal94 & "," & HVal95 & "," & HVal96 & "," & HVal97 & "," & HVal98 & "," & HVal99 & "," & HVal100 & "," & HVal101 & "," & HVal102 & "," & HVal103 & ") " & _
"Values(" & VVal1 & "," & VVal2 & "," & VVal3 & "," & VVal4 & "," & VVal5 & "," & VVal6 & "," & VVal7 & "," & VVal8 & "," & VVal9 & "," & VVal10 & "," & VVal11 & "," & VVal12 & "," & VVal13 & "," & VVal14 & "," & VVal15 & "," & VVal16 & "," & VVal17 & "," & VVal18 & "," & VVal19 & "," & VVal20 & "," & VVal21 & "," & VVal22 & "," & VVal23 & "," & VVal24 & "," & VVal25 & "," & VVal26 & "," & VVal27 & "," & VVal28 & "," & VVal29 & "," & VVal30 & "," & VVal31 & "," & VVal32 & "," & VVal33 & "," & VVal34 & "," & VVal35 & "," & VVal36 & "," & VVal37 & "," & VVal38 & "," & VVal39 & "," & VVal40 & "," & VVal41 & "," & VVal42 & "," & VVal43 & "," & VVal44 & "," & VVal45 & "," & VVal46 & "," & VVal47 & "," & VVal48 & "," & VVal49 & "," & VVal50 & "," & _
VVal51 & "," & VVal52 & "," & VVal53 & "," & VVal54 & "," & VVal55 & "," & VVal56 & "," & VVal57 & "," & VVal58 & "," & VVal59 & "," & VVal60 & "," & VVal61 & "," & VVal62 & "," & VVal63 & "," & VVal64 & "," & VVal65 & "," & VVal66 & "," & VVal67 & "," & VVal68 & "," & VVal69 & "," & VVal70 & "," & VVal71 & "," & VVal72 & "," & VVal73 & "," & VVal74 & "," & VVal75 & "," & VVal76 & "," & VVal77 & "," & VVal78 & "," & VVal79 & "," & VVal80 & "," & VVal81 & "," & VVal82 & "," & VVal83 & "," & VVal84 & "," & VVal85 & "," & VVal86 & "," & VVal87 & "," & VVal88 & "," & VVal89 & "," & VVal90 & "," & VVal91 & "," & VVal92 & "," & VVal93 & "," & VVal94 & "," & VVal95 & "," & VVal96 & "," & VVal97 & "," & VVal98 & "," & VVal99 & "," & VVal100 & "," & VVal101 & "," & VVal102 & "," & VVal103 & ") """
HVal values are simple cell.value references. VVal values are the same, the idea is that HVals get set, then a loop gets kicked off, assign VVals, update SQL, fire it through the update engine, repeat until the file is fully imported.
Here is where I am stuck. If I run the compile for the SQL statement, print the resulting string to a cell, ie:
Workbooks("Tool.xlsm").Sheets("Buttons").Cells(1, 1).Value = SQL
Manually copy that string from Workbooks("Tool.xlsm").Sheets("Buttons").Cells(1, 1).Value, and paste it directly into a 'SQL=""' statement, then run the update, it works.
If instead of printing the value to the cell, I just send the original SQL statement into the update module, I get a "An Object or Column Name is missing" error.
If I re-set SQL to equal the value of the cell the original SQL was printed into, ie:
Workbooks("Tool.xlsm").Sheets("Buttons").Cells(1, 1).Value = SQL
SQL = Workbooks("Tool.xlsm").Sheets("Buttons").Cells(1, 1).Value
and send it to the update module, same "An Object or Column Name is missing" error.
The only time it is working is when I copy the string generated by the first chunk of code and printed to cell Workbooks("Tool.xlsm").Sheets("Buttons").Cells(1, 1).Value, paste it back into the VBA editor, close it off with quotations, and store it as "SQL=".
Does the ring any bells for anyone for why I get these error messages for 2 hands off methods of generating the "SQL" variable, but a seemingly straight forward manual step that isnt really changing anything gets things to work?
Embarrassingly lowest hanging fruit possible.
Last 3 characters of the dynamic SQL statement are '"""'. Get rid of the 2 erroneous double quotes and the statement getting stored in the variable doesn't end ')"'.
Copying it from the cell and pasting it back into the vb editor, I was adding 3 quotation marks to manually build the statement where I should have been needing to add 4.
I want to output selected parameters from movie files.
I'm doing this in that way:
arrGeneral = Array("General;Video Format List: %Video_Format_List%","General;File name: %FileNameExtension%","General;Commercial name: %Format_Commercial%")
arrVideo = Array("Video;ID: %ID%","Video;Format: %Format/String%","Video;Format info: %Format/Info%","Video;Format profile: %Format_Profile%","Video;Bit rate: %BitRate/String%")
arrAudio = Array("Audio;ID: %ID%\n","Audio;Format: %Format%\n","Audio;Format info: %Format/Info%\n","Audio;Commercial name: %Format_Commercial%\n","Audio;Codec ID: %CodecID%\n")
arrText = Array("Text;ID: %ID%\n","Text;Format: %Format/String%\n","Text;Codec ID: %CodecID/Info%\n","Text;Title: %Title%\n","Text;Language: %Language/String%\n")
' == General section ==
objFileToWrite.Write "General" & vbCrLf
for i = 0 to UBound(arrGeneral)
commandToRun = chr(34) & ProgramToExecute & chr(34) & " --Output=" & chr(34) & arrGeneral(i) & chr(34) & " " & chr(34) & InVideoFile & chr(34)
result = CreateObject("WScript.Shell").Exec(commandToRun).StdOut.ReadAll
objFileToWrite.Write result
next
objFileToWrite.Write "----------" & vbCrLf
' == Video section ==
objFileToWrite.Write "Video" & vbCrLf
for i = 0 to UBound(arrVideo)
commandToRun = chr(34) & ProgramToExecute & chr(34) & " --Output=" & chr(34) & arrVideo(i) & chr(34) & " " & chr(34) & InVideoFile & chr(34)
result = CreateObject("WScript.Shell").Exec(commandToRun).StdOut.ReadAll
objFileToWrite.Write result
next
objFileToWrite.Write "----------" & vbCrLf
' == Audio section ==
' Here is a problem beacuse it might be more than 1 Audio stream
objFileToWrite.Write "Audio" & vbCrLf
for i = 0 to UBound(arrAudio)
commandToRun = chr(34) & ProgramToExecute & chr(34) & " --Output=" & chr(34) & arrAudio(i) & chr(34) & " " & chr(34) & InVideoFile & chr(34)
result = CreateObject("WScript.Shell").Exec(commandToRun).StdOut.ReadAll
objFileToWrite.Write result
next
objFileToWrite.Write "----------" & vbCrLf
For General and Video streams these commands (examples):
MediaInfo.exe --Output="General;Video Format List: %Video_Format_List%" "Sample.mkv"
MediaInfo.exe --Output="Video;Format info: %Format/Info%" "Sample.mkv"
are generating single line results like for instance:
Video Format List: HEVC
Format info: High Efficiency Video Coding
so my script is properly creating output file that contain:
General
Video Format List: HEVC
File name: Sample.mkv
Commercial name: Matroska
Format version: Version 4
File size: 10.03 GiB
Duration: 1 h 52 min 15 s 744 ms
Overall bit rate: 12.8 Mb/s
----------
Video
ID: 1
Format: HEVC
Format info: High Efficiency Video Coding
Format profile: Main 10#L4#Main
Bit rate: 8 525 kb/s
Width: 1 920 pixels
Height: 1 080 pixels
Display aspect ratio: 1.778
Display aspect ratio: 16:9
Frame rate mode: Constant
Frame rate: 23.976 (24000/1001) FPS
Color space: YUV
Chroma subsampling: 4:2:0
Bit depth: 10 bits
Video stream size: 6.68 GiB (67%)
----------
But for the Audio and Text (subtitle) there might be more than one stream and the single command:
MediaInfo.exe --Output="Audio;Format info: %Format/Info%\n" "Sample.mkv"
is generating two or more lines (depends on how many streams movie file contain) like this:
Format info: Digital Theater Systems
Format info: Audio Coding 3
As the result in output file I'm getting something like this:
Audio
ID: 2
ID: 3
Format: DTS
Format: AC-3
Format info: Digital Theater Systems
Format info: Audio Coding 3
Commercial name: DTS-HD Master Audio
Commercial name: Dolby Digital
Codec ID: A_DTS
Codec ID: A_AC3
Bit rate: 3 958 kb/s
Bit rate: 192 kb/s
but expected result is:
Audio #2
ID: 2
Format: DTS
Format info: Digital Theater Systems
Commercial name: DTS-HD Master Audio
Codec ID: A_DTS
Bit rate: 3 958 kb/s
Audio #3
ID: 3
Format: AC-3
Format info: Audio Coding 3
Commercial name: Dolby Digital
Codec ID: A_AC3
Bit rate: 192 kb/s
I think it would be necessary to insert "multiline" results of Audio and Text streams into some dynamic arrays and in the next step to go through them and insert into output file "sorted" values or the second option is to sort final output file but in both cases but I have no clue how to do that.
Here is the vbs script that can be used to collect selected attributes:
InVideoFile = "C:\Temp\Sample.mkv"
InVideoFile = replace(InVideoFile,chr(34),"")
inFile = Left(InVideoFile, Len(InVideoFile) -4) & "-All.txt"
outFile = Left(inFile, Len(inFile) -4) & "-MediaInfo.txt"
Set objFSO = CreateObject("Scripting.FileSystemObject")
if objFSO.FileExists(inFile) then
objFSO.DeleteFile inFile
end if
' MediaInfo.exe location below in ProgramToExecute variable
' MediaInfo.exe (Interface CLI) download location: https://mediaarea.net/en/MediaInfo/Download/Windows
ProgramToExecute = "C:\Program Files\MediaInfo\MediaInfo_CLI\MediaInfo.exe"
commandToRun = "cmd /C " & chr(34) & chr(34) & ProgramToExecute & chr(34) & " -f " & chr(34) & InVideoFile &chr(34) & " > " &chr(34) & inFile &chr(34) & chr(34)
Dim objShell
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run commandToRun,1,true
Set objShell = Nothing
Set objFileToRead = objFSO.OpenTextFile(inFile, 1)
Set objFileToWrite = objFSO.CreateTextFile(outFile,True)
Dim arrGeneral
Dim arrVideo
Dim arrAudio
Dim arrText
' Attributes that are need to be collected are taken from the result of command MediaInfo.exe --Info-Parameters
' Arrays elements are build in the following way:
' section;Text %Attribute%Delimiter
' examples:
' "General;Video Format List: %Video_Format_List%"
' "Video;Format profile: %Format_Profile%"
' "Audio;Channel(s): %Channel(s)/String%|"
' "Text;Format: %Format/String%|"
' Audio and Text sections might contain more than one stream. Result is delimited by "|" character (can be used another) and later on is split
arrGeneral = Array("General;Video Format List: %Video_Format_List%","General;File name: %FileNameExtension%","General;Commercial name: %Format_Commercial%","General;Format version: %Format_Version%","General;File size: %FileSize/String4%","General;Duration: %Duration/String1%","General;Overall bit rate: %OverallBitRate/String%")
arrVideo = Array("Video;ID: %ID%","Video;Format: %Format/String%","Video;Format info: %Format/Info%","Video;Format profile: %Format_Profile%","Video;Bit rate: %BitRate/String%","Video;Width: %Width/String%","Video;Height: %Height/String%","Video;Display aspect ratio: %DisplayAspectRatio/String%","Video;Frame rate mode: %FrameRate_Mode/String%","Video;Frame rate: %FrameRate/String%","Video;Color space: %ColorSpace%","Video;Chroma subsampling: %ChromaSubsampling/String%","Video;Bit depth: %BitDepth/String%","Video;Video stream size: %StreamSize/String5%","Video;Colour primaries: %colour_primaries%","Video;Transfer characteristices: %transfer_characteristics%","Video;Matrix coefficients: %matrix_coefficients%")
arrAudio = Array("Audio;ID: %ID%|","Audio;Format: %Format%|","Audio;Format info: %Format/Info%|","Audio;Commercial name: %Format_Commercial%|","Audio;Codec ID: %CodecID%|","Audio;Bit rate: %BitRate/String%|","Audio;Channel(s): %Channel(s)/String%|","Audio;Channel positions: %ChannelPositions%|","Audio;Channel layout: %ChannelLayout%|","Audio;Sampling rate: %SamplingRate/String%|","Audio;Bit depth: %BitDepth/String%|","Audio;Compression mode: %Compression_Mode/String%|","Audio;Audio stream size: %StreamSize/String5%|","Audio;Title: %Title%|","Audio;Language: %Language/String%|","Audio;Default: %Default/String%|","Audio;Forced: %Forced/String%|")
arrText = Array("Text;ID: %ID%|","Text;Format: %Format/String%|","Text;Codec ID: %CodecID/Info%|","Text;Title: %Title%|","Text;Language: %Language/String%|","Text;Default: %Default/String%|","Text;Forced: %Forced/String%|")
' == General section ==
objFileToWrite.Write "General" & vbCrLf
for i = 0 to UBound(arrGeneral)
commandToRun = chr(34) & ProgramToExecute & chr(34) & " --Output=" & chr(34) & arrGeneral(i) & chr(34) & " " & chr(34) & InVideoFile & chr(34)
result = CreateObject("WScript.Shell").Exec(commandToRun).StdOut.ReadAll
resultNoCRLF = Replace(result, vbCRLF, "")
if right(resultNoCRLF,2) <> ": " then
objFileToWrite.Write result
end if
next
objFileToWrite.Write "----------" & vbCrLf
' == Video section ==
objFileToWrite.Write "Video" & vbCrLf
for i = 0 to UBound(arrVideo)
commandToRun = chr(34) & ProgramToExecute & chr(34) & " --Output=" & chr(34) & arrVideo(i) & chr(34) & " " & chr(34) & InVideoFile & chr(34)
result = CreateObject("WScript.Shell").Exec(commandToRun).StdOut.ReadAll
resultNoCRLF = Replace(result, vbCRLF, "")
if right(resultNoCRLF,2) <> ": " then
objFileToWrite.Write result
end if
next
objFileToWrite.Write "----------" & vbCrLf
' == Audio section ==
' It might be more than 1 Audio stream
objFileToWrite.Write "Audio" & vbCrLf
for i = 0 to UBound(arrAudio)
commandToRun = chr(34) & ProgramToExecute & chr(34) & " --Output=" & chr(34) & arrAudio(i) & chr(34) & " " & chr(34) & InVideoFile & chr(34)
result = CreateObject("WScript.Shell").Exec(commandToRun).StdOut.ReadAll
Dim arrAudioSplit
arrAudioSplit = Split(result,"|")
ReDim Preserve arrA(UBound(arrAudio),UBound(arrAudioSplit)-1)
for z = 0 to UBound(arrAudioSplit)-1
arrA(i,z) = arrAudioSplit(z)
next
next
for j = 0 to Ubound(arrAudioSplit) - 1
for k = 0 to Ubound(arrAudio)
if right(arrA(k,j),2) <> ": " then
objFileToWrite.Write arrA(k,j) & vbCrLf
end if
next
objFileToWrite.Write "----------" & vbCrLf
next
' == Text (subtitles) section ==
' It might be more than 1 Text stream
objFileToWrite.Write "Text" & vbCrLf
for i = 0 to UBound(arrText)
commandToRun = chr(34) & ProgramToExecute & chr(34) & " --Output=" & chr(34) & arrText(i) & chr(34) & " " & chr(34) & InVideoFile & chr(34)
result = CreateObject("WScript.Shell").Exec(commandToRun).StdOut.ReadAll
Dim arrTextSplit
arrTextSplit = Split(result,"|")
ReDim Preserve arrT(UBound(arrText),UBound(arrTextSplit)-1)
for z = 0 to UBound(arrTextSplit)-1
arrT(i,z) = arrTextSplit(z)
next
next
for j = 0 to Ubound(arrTextSplit) - 1
for k = 0 to Ubound(arrText)
if right(arrT(k,j),2) <> ": " then
objFileToWrite.Write arrT(k,j) & vbCrLf
end if
next
objFileToWrite.Write "----------" & vbCrLf
next
' == Menu (Chapters) section ==
' Have to be handled in different way by checking result of the command MediaInfo.exe -f inputfile
Set objFileToRead = objFSO.OpenTextFile(inFile, 1)
startReadingMenu = false
menuNextLine = 1
do while not objFileToRead.AtEndOfStream
strLineOriginal = Trim(objFileToRead.ReadLine())
MenuNextLine = MenuNextLine + 1
if Left(strLineOriginal,16) = "Chapters_Pos_End" then
startReadingMenu = true
MenuNextLine = 0
end if
if startReadingMenu then
objFileToWrite.Write "Chapters" & vbCrLf
startReadingMenu = false
end if
if MenuNextLine = 1 then
objFileToWrite.Write strLineOriginal & vbCrLf
MenuNextLine = 0
end if
loop
' Close files
objFileToRead.Close
Set objFileToRead = Nothing
objFileToWrite.Close
Set objFileToWrite = Nothing
' Dislay result file in notepad
DisplayInNotepad = "notepad.exe " & chr(34) & outFile &chr(34)
commandToRun = "cmd /C " & DisplayInNotepad
Dim objSh
Set objSh = WScript.CreateObject("WScript.Shell")
objSh.Run commandToRun,0,true
Set objSh = Nothing
' Cleanup
if objFSO.FileExists(inFile) then
objFSO.DeleteFile inFile
end if
if objFSO.FileExists(outFile) then
objFSO.DeleteFile outFile
end if
The only remaining issue is how to hide cmd window that is blinking when the line is invoked:
result = CreateObject("WScript.Shell").Exec(commandToRun).StdOut.ReadAll
but this is cosmetic issue.
I am using Access to run VBA code. I have an array that runs through a recordset query "rstQueryTrainings". In this query, there are multiple rows per ID. What I would like this array to do is be able to identify if a row contains the first unique ID in rstQueryTrainings, and if so create a character string. If it is not the first unique ID in the recordset, then create a different character string. To note, these character strings make up a body of an email. My code uses the Recordset Findfirst property, and if there is a match then bookmark that record. If the record is bookmarked then run character string. If it is not bookmarked, then run a different character string. I get the following error:
Error 3077: Syntax error (comma) in expression
I'm not sure if this error is popping up because I'm using FindFirst in an array.
requiredTrain = ""
If tArraySize <> -1 Then
ID = ""
For eachTraining = 0 To tArraySize
ID = PersonnelCompList(eachTraining)
Debug.Print ID
IDstring = "PersonnelCompList = " & ID
Debug.Print IDstring
rstQueryTrainings.FindFirst IDstring
If Not rstQueryTrainings.NoMatch Then
rstQueryTrainings.Bookmark = varFirstMark
End If
If IsEmpty(rstQueryTrainings.Bookmark) Then
requiredTrain = requiredTrain + "<LI>" & "<b>Course</b>: " & ", " & trainingList(eachTraining) & ", <b>Number</b>: " & courseNumList(eachTraining) & ", <b>Link</b>: " & courseNumList(eachTraining) & " | </b>" & statusList(eachTraining) & "</b>" & " (" & daysRemaining(eachTraining) & " days remaining)" & "</LI>"
Else
requiredTrain = requiredTrain + "<b>Personnel Due</b>: " & PersonnelCompList(eachTraining) & "<LI>" & "<b>Course</b>: " & ", " & trainingList(eachTraining) & ", <b>Number</b>: " & courseNumList(eachTraining) & ", <b>Link</b>: " & courseNumList(eachTraining) & " | </b>" & statusList(eachTraining) & "</b>" & " (" & daysRemaining(eachTraining) & " days remaining)" & "</LI>"
End If
Debug.Print requiredTrain
Next eachTraining
End If
I'm not sure what the Bookmarks are for. This should do:
requiredTrain = ""
For eachTraining = 0 To tArraySize
ID = PersonnelCompList(eachTraining)
Debug.Print ID
IDstring = "PersonnelCompList = " & ID
Debug.Print IDstring
rstQueryTrainings.FindFirst IDstring
If rstQueryTrainings.NoMatch Then
requiredTrain = requiredTrain + "<LI>" & "<b>Course</b>: " & ", " & trainingList(eachTraining) & ", <b>Number</b>: " & courseNumList(eachTraining) & ", <b>Link</b>: " & courseNumList(eachTraining) & " | </b>" & statusList(eachTraining) & "</b>" & " (" & daysRemaining(eachTraining) & " days remaining)" & "</LI>"
Else
requiredTrain = requiredTrain + "<b>Personnel Due</b>: " & PersonnelCompList(eachTraining) & "<LI>" & "<b>Course</b>: " & ", " & trainingList(eachTraining) & ", <b>Number</b>: " & courseNumList(eachTraining) & ", <b>Link</b>: " & courseNumList(eachTraining) & " | </b>" & statusList(eachTraining) & "</b>" & " (" & daysRemaining(eachTraining) & " days remaining)" & "</LI>"
End If
Debug.Print requiredTrain
Next eachTraining
I need to recurse a folder and all subfolders and move the pdf files to another folder. Looking here I tried the below but it seems to continuously run (the script never ends) but it does move the files.
I would also like to count the source files, recurse folder and move pdf (ignore case) files, count destinations files. If source and destination are equal then run dir *.pdf > trust.csv and send a success email
Set fso = CreateObject("Scripting.FileSystemObject")
Set Message = CreateObject("CDO.Message")
Set Shell = WScript.CreateObject("WScript.Shell")
Set shell = CreateObject("Wscript.shell")
'Specify variables for Emails
strScriptServer = "ASFOXTECHOPS01"
strScriptPath = "\\techopspc01\c$\scripts\WM..."
strScriptName = "[WM-01]-WMScansToCenterDoc.vbs"
'strToEmail = ""
strCCEmail = ""
strCCEmailFail = ""
strProcessID = "[WM-01]"
strCustomerImpact = "LOW"
strCorporateImpact = "LOW"
strDocumentation = "\\FSCHAFOX01\GROUP_SHARE\Tech Group\Documentation\Automation\"
blnEmailNotification = false
'Specify variables for File Paths
'strFromPath1 = "\\fschauni01\GROUP_SHARE\Wealth Management\Scanning\ZAstrosky\"
strToPath1 = "\\fschauni01\GROUP_SHARE\Wealth Management\Tech\"
strToArchive1 = "\\fschauni01\GROUP_SHARE\Wealth Management\Scanning\" & StrYear & "_" & strMonth
'BROKE************CREATE ARCHIVE FOLDER IF IT DOES NOT EXIST
'If FSO.FolderExists(strToArchive1) Then
'Proceed
'Else
' FSO.CreateFolder("\\fschauni01\GROUP_SHARE\Wealth Management\Scanning\" & StrYear & "_" & strMonth)
'End If
'DELETE FILES FROM THE strToPath(s) TO AVOID OVERWRITE ERRORS
FSO.DeleteFile (strToPath1 & "*.*")
testfolder = "\\fschauni01\GROUP_SHARE\Wealth Management\Tech\"
MoveFiles fso.GetFolder("\\fschauni01\GROUP_SHARE\Wealth Management\Scanning\ZAstrosky")
blnEmailNotification = True
'Email
'If Err <> 0 Then
' blnEmailNotification = false
' HandleError
'End If
If blnEmailNotification = True Then
'Send Results email
objMessage.Subject = "SUCCESS - " & strProcessID & " - WM Scanned Reports Imported into CenterDoc"
objMessage.From = "IT Automation"
objMessage.Sender = ""
'objMessage.To = strToEmail
objMessage.Cc = strCCEmail
objMessage.TextBody = "---------------SCRIPT SUCCESSFUL---------------" & vbnewline & VbCrLf & "Script successfully moved the files with no errors." & vbnewline & vbcrlf & "- Script Name:" & VbTab & VbTab & VbTab & strScriptName & VbNewLine & VbCrLf & "- Script Origination:" & VbTab & VbTab & strScriptServer & VbNewline & VbCrLf & "- Script Path:" & VbTab & VbTab & VbTab & strScriptPath & VbNewLine & VbCrLf & "- Documentation:" & VbTab & VbTab & strDocumentation & VbNewLine & VbCrLf & "- Set1:" &VbTab & VbTab & "Souce Files = " & sourcecount1 & VbTab & VbTab & "Destination Files = " & destcount1 & VbTab & VbTab & "Archive Files = " & archivecount1 & VbTab & VbTab & "------------------------------------------------------------"
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = ""
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objMessage.Configuration.Fields.Update
objMessage.Send
Else
'Do Nothing
End If
Sub HandleError
strErrorMessage = "Error Number " & Err.Number & ":" & Err.Description
objMessage.Subject = "SCRIPT ERROR - " & strProcessID & " - IMMEDIATE ACTION REQUIRED"
objMessage.From = "IT Automation"
objMessage.Sender = ""
objMessage.To = strToEmail
'objMessage.Cc = strCCEmail
objMessage.TextBody = "---------------SCRIPT ERROR---------------" & vbnewline & VbCrLf & "Script Name:" & VbTab & VbTab & VbTab & strScriptName & VbNewLine & VbCrLf & "Customer Impact:" & VbTab & VbTab & VbTab & strCustomerImpact & VbNewLine & VbCrLf & "Corporate Impact:" & VbTab & VbTab & VbTab & strCorporateImpact & VbNewLine & VbCrLf & "Error Description:" & VbTab & VbTab & VbTab & Err.Description & vbnewline & VbCrLf & "Error Number:" & VbTab & VbTab & VbTab & Err.Number & VbCrLf & VbNewLine & "Script Location:" & VbTab & VbTab & VbTab & strScriptServer & VbCrLf & VbNewLine & "Script Path:" & VbTab & VbTab & VbTab & strScriptPath & VbNewline & VbCrLf & "Documentation:" & VbTab & VbTab & strDocumentation & VbNewLine & VbCrLf & "-------------------------------------------------"
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = ""
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objMessage.Configuration.Fields.Update
objMessage.Send
Err.Clear
End Sub
Sub MoveFiles(fldr)
For Each f In fldr.Files
basename = fso.GetBaseName(f)
extension = fso.GetExtensionName(f)
If LCase(extension) = "pdf" Then
dest = fso.BuildPath(testfolder, f.Name)
Do While fso.FileExists(dest)
dest = fso.BuildPath(testfolder, basename & "." & extension)
Loop
f.Move dest
End If
Next
For Each sf In fldr.SubFolders
MoveFiles sf
Next
End Sub
Edited original code for more help.
thanks Zoyd
astro
You move all the pdf files from \\fschauni01\GROUP_SHARE\Wealth Management\Scanning\ZAstrosky and its subfolders to \\fschauni01\GROUP_SHARE\Wealth Management\Scanning\ZAstrosky\Tech. Your recursion logic is sound, but there is another problem: your destination folder is a subfolder of your source folder. Thus, your script keeps copying files from \\fschauni01\GROUP_SHARE\Wealth Management\Scanning\ZAstrosky\Tech to itself. Whether this works or not, it is a bad idea to do a foreach loop on a collection and modify its content.
The main problem is that this while loop will never end if it is taken at all, and in this case, it is taken. When your recursion reaches the destination folder, all the files already exist in the destination folder (obviously), the loop is taken and there is no way out of it.
If LCase(extension) = "pdf" Then
dest = fso.BuildPath(testfolder, f.Name)
Do While fso.FileExists(dest)
dest = fso.BuildPath(testfolder, basename & "." & extension)
Loop
f.Move dest
End If
As for the matter of counting files, does folder.Files.Count not work ? (if you need a recursive count, I'am afraid you'll have to do it yourself, but you know how).
After your edit, the code still contains this:
Do While fso.FileExists(dest)
dest = fso.BuildPath(testfolder, basename & "." & extension) ' ☠
Loop
So, for example, if a file a.pdf exists in "\\fschauni01\GROUP_SHARE\Wealth Management\Scanning\ZAstrosky\docs1" and in "\\fschauni01\GROUP_SHARE\Wealth Management\Scanning\ZAstrosky\docs2", your script will find that a.pdf already exists in the archive directory and enters the infinite loop. A way around this is to recreate the directory structure in the archive directory (each time you call MoveFiles on directoryA, create directoryA in the archive directory and move files there).
What is wrong with this script?
Option Explicit
Dim objRootDSE, strDNSDomain, adoConnection
Dim strBase, strFilter, strAttributes, strQuery, adoRecordset
Dim dtmStart, dtmEnd, strStart, strEnd
Dim strID, strFirst, strLast, strNTName
dtmEnd = Now()
dtmStart = DateAdd("d", -7, dtmEnd)
strStart = CStr(Year(dtmStart)) _
& Right("0" & CStr(Month(dtmStart)), 2) _
& Right("0" & CStr(Day(dtmStart)), 2) & "000000.0Z"
strEnd = CStr(Year(dtmEnd)) _
& Right("0" & CStr(Month(dtmEnd)), 2) _
& Right("0" & CStr(Day(dtmEnd)), 2) & "235959.0Z"
' Determine DNS domain name.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
' Use ADO to search Active Directory.
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
Set adoRecordset = CreateObject("ADODB.Recordset")
adoRecordset.ActiveConnection = adoConnection
' Search entire domain.
strBase = "<LDAP://" & strDNSDomain & ">"
'For user accounts for people created in the last week
strFilter = "(&(objectCategory=person)(objectClass=user)" _
& "(whenCreated>=" & strStart & ")(whenCreated<=" & strEnd & "))"
' Comma delimited list of attribute values to retrieve.
strAttributes = "employeeID,sn,givenName,sAMAccountName"
' Construct the LDAP query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
' Run the query.
adoRecordset.Source = strQuery
adoRecordset.Open
' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
' Retrieve values.
strID = adoRecordset.Fields("employeeID").Value
strLast = adoRecordset.Fields("sn").Value
strFirst = adoRecordset.Fields("givenName").Value
strNTName = adoRecordset.Fields("sAMAccountName").Value
Wscript.Echo """" & strID & """,""" & strLast & """,""" & strFirst
& """,""" & strNTName & """"
adoRecordset.MoveNext
Loop
' Clean up.
adoRecordset.Close
adoConnection.Close
cscript //nologo test.vbs > users.csv
returns
(53, 1) Microsoft VBScript compilation error: Expected statement
You're missing an underscore line continuation at the end of the first line of this snippet:
Wscript.Echo """" & strID & """,""" & strLast & """,""" & strFirst
& """,""" & strNTName & """"
It should look like this:
Wscript.Echo """" & strID & """,""" & strLast & """,""" & strFirst _
& """,""" & strNTName & """"