3

I have below script, in this there are two path one is Target path (only one) and another source path (variables).

About below script function: I'll run this once in a month and it'll go the souce path (10 path) and copy lates file then copy&rename to target path (common for all the files).

note : file which is copyed form the respacted source should be rename as per script like: file from "F:\Financial\Data\Reports\AccruntPnLMTD" should be rename as "PNL.csv"

@echo off
setlocal
set DateFolder=04.2013
set TargetFolder=F:\Financial\Data\%DateFolder%\Final Reports

:: copy the newest file from AccruntPnLMTD and rename it to PNL.csv
call :copyAndRename "F:\Financial\Data\Reports\AccruntPnLMTD" "%TargetFolder%\PNL.csv"

:: copy the newest file from AccountPnlMTD and rename it to AC.csv
call :copyAndRename "F:\Financial\Data\Reports\AccountPnlMTD" "%TargetFolder%\AC.csv"

:: copy the newest file from ExpensesMTD and rename it to EXPMTD.csv
call :copyAndRename "F:\Financial\Data\Reports\ExpensesMTD" "%TargetFolder%\EXPMTD.csv"

:: copy the newest file from ExpensesYTD and rename it to EXPYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\ExpensesYTD" "%TargetFolder%\EXPYTD.csv"

:: copy the newest file from AccrualPnLYTD and rename it to PNLYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\AccrualPnLYTD" "%TargetFolder%\PNLYTD.csv"

:: copy the newest file from AccountYTD and rename it to ACYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\AccountYTD" "%TargetFolder%\ACYTD.csv"

:: copy the newest file from BalanceMTD and rename it to BSMTD.csv
call :copyAndRename "F:\Financial\Data\Reports\BalanceMTD" "%TargetFolder%\BSMTD.csv"

:: copy the newest file from BalanceYTD and rename it to BSYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\BalanceYTD" "%TargetFolder%\BSYTD.csv"

:: copy the newest file from FinancialStmtMTD and rename it to FSMTD.csv
call :copyAndRename "F:\Financial\Data\Reports\FinancialStmtMTD" "%TargetFolder%\FSMTD.csv"

:: copy the newest file from FinancialStmtYTD and rename it to FSYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\FinancialStmtYTD" "%TargetFolder%\FSYTD.csv"


:: Done
goto :eof

:copyAndRename
set SourceFolder=%~1
set TargetFile=%~2

:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%SourceFolder%"') do set "NewestFile=%%F"

:: copy and rename it to the target
copy "%SourceFolder%\%NewestFile%" "%TargetFile%"


:: Done with this subroutine
goto :eof

I want's to give both path after run the script (popup should ask for the path)

Sysyphus
  • 1,061
  • 5
  • 10
niki niki
  • 187
  • 1
  • 2
  • 9
  • I am not sure I understood your needs. My answer may not have been specific enough. – foxidrive May 29 '13 at 14:10
  • no your answare was good I am gatting the popup for both the path. bt it's giving the error "the system cannot find the file specified" – niki niki May 29 '13 at 14:48
  • Do I need to change my old script source path like "call :copyAndRename "F:\Financial\Data\Reports\AccruntPnLMTD" "%TargetFolder%\PNL.csv" to "call :copyAndRename "%sourcefolder%" "%TargetFolder%\PNL.csv" b,z I don't want to give sourcepath in the script. – niki niki May 29 '13 at 14:50
  • http://stackoverflow.com/questions/15885132/file-folder-chooser-dialog-from-a-windows-batch-script – David Ruhmann May 29 '13 at 15:55
  • Do you want to pick the source folder for all the files that are being copied? So each file may come from **F:\Financial\Data\Reports\** or some other place like **F:\Old Financial Reports\data\** ? – foxidrive May 30 '13 at 00:46
  • F:\Financial\Data\Reports\ till reports folder source will remane same then folders will change for each file like AccruntPnLMTD,ExpensesMTD. – niki niki May 30 '13 at 07:41
  • (a)F:\Financial\Data\Reports\AccruntPnLMTD\accrunt.csv will rename as PNL.csv, (b)F:\Financial\Data\Reports\ExpensesMTD\expneses.csv will rename as EXPMTD.csv...same like others – niki niki May 30 '13 at 07:52

2 Answers2

0

This is untested - it merges your code with the popup routine and asks for the source folder once, where all the folders are expected to be.

@echo off
setlocal
set DateFolder=04.2013
:: set the source and target folders
call :getpath

set "TargetFolder=%TargetFolder%\%DateFolder%\Final Reports"


:: copy the newest file from AccruntPnLMTD and rename it to PNL.csv
call :copyAndRename "AccruntPnLMTD" "%TargetFolder%\PNL.csv"

:: copy the newest file from AccountPnlMTD and rename it to AC.csv
call :copyAndRename "AccountPnlMTD" "%TargetFolder%\AC.csv"

:: copy the newest file from ExpensesMTD and rename it to EXPMTD.csv
call :copyAndRename "ExpensesMTD" "%TargetFolder%\EXPMTD.csv"

:: copy the newest file from ExpensesYTD and rename it to EXPYTD.csv
call :copyAndRename "ExpensesYTD" "%TargetFolder%\EXPYTD.csv"

:: copy the newest file from AccrualPnLYTD and rename it to PNLYTD.csv
call :copyAndRename "AccrualPnLYTD" "%TargetFolder%\PNLYTD.csv"

:: copy the newest file from AccountYTD and rename it to ACYTD.csv
call :copyAndRename "AccountYTD" "%TargetFolder%\ACYTD.csv"

:: copy the newest file from BalanceMTD and rename it to BSMTD.csv
call :copyAndRename "BalanceMTD" "%TargetFolder%\BSMTD.csv"

:: copy the newest file from BalanceYTD and rename it to BSYTD.csv
call :copyAndRename "BalanceYTD" "%TargetFolder%\BSYTD.csv"

:: copy the newest file from FinancialStmtMTD and rename it to FSMTD.csv
call :copyAndRename "FinancialStmtMTD" "%TargetFolder%\FSMTD.csv"

:: copy the newest file from FinancialStmtYTD and rename it to FSYTD.csv
call :copyAndRename "FinancialStmtYTD" "%TargetFolder%\FSYTD.csv"


:: Done
goto :eof

:copyAndRename
set "FileFolder=%SourceFolder%\%~1"
set "TargetFile=%~2"

echo copying "%FileFolder%"

:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%FileFolder%"') do set "NewestFile=%%F"

:: copy and rename it to the target
copy "%FileFolder%\%NewestFile%" "%TargetFile%" >nul


:: Done with this subroutine
goto :eof

:getsourcepath

Call :BrowseFolder "Choose Source folder" "C:\Program Files\"
Set "SourceFolder=%Result%"

Call :BrowseFolder "Choose Target folder" "C:\Users\"
Set TargetFolder=%Result% 

REM echo %SourceFolder%
REM echo %TargetFolder%

:: Done
goto :eof


:BrowseFolder
set Result=
set input="%~1" & set default="%~2"
:: Temporary files
set vbs=%temp%\_.vbs
set tmp=%temp%\_.cmd
:: Build VBScript file
findstr "'%skip%VBS" "%~f0" > "%vbs%"
:: Run the script with WSH and set Path as Env variable %Result%
for /f "delims=" %%a in ('cscript /nologo "%vbs%" ') do set "Result=%%a"
DEL %VBS%
set vbs= & set tmp= & set input= & set default=
goto :EOF

set WshShell=WScript.CreateObject("WScript.Shell") 'VBS
set shell=WScript.CreateObject("Shell.Application") 'VBS
sInput=WshShell.ExpandEnvironmentStrings("%input%") 'VBS
sDefault=WshShell.ExpandEnvironmentStrings("%default%") 'VBS
sInput = Replace(sInput, chr(34), "") 'VBS
sDefault = replace(sDefault,chr(34),"") 'VBS
set folder=shell.BrowseForFolder(0,sInput,0,sDefault) 'VBS
if typename(folder)="Nothing" Then  'VBS
wscript.echo "set Result=Dialog Cancelled" 'VBS
WScript.Quit(1) 'VBS
end if 'VBS
set folderItems=folder.Items() 'VBS
set folderItem=folderItems.Item() 'VBS
pathname=folderItem.Path 'VBS
wscript.echo pathname 'VBS
foxidrive
  • 40,353
  • 10
  • 53
  • 68
  • thx foxi..coudn't understood about 7 & 8 lines how these'll be replaced & I dont' see the concept of newest file in your ans ":: Find the newest file in the source folder for /f "tokens=*" %%F in ('dir /b /od /a-d "%SourceFolder%"') do set "NewestFile=%%F" " – niki niki May 29 '13 at 11:57
  • All it does is fill in the values for `%SourceFolder%` and `%TargetFolder%` from a gui popup so you can use them in your batch file. You can use it like a subroutine to fill in those variables. – foxidrive May 29 '13 at 13:15
  • I added more into to the answer. – foxidrive May 29 '13 at 13:20
  • It would be great fox if you could club both macro on one page..I am bit canfuse..thx a lot – niki niki May 29 '13 at 13:22
  • :: copy the newest file from AccrualPnLMTD and rename it to AccrualMTD.csv call :copyAndRename "I:\clients\All Clients\Financial Control\Permanent\Datamart Reports\PWCM\PWMF\AccrualPnLMTD" "%TargetFolder%\AccrualMTD.csv" – niki niki May 29 '13 at 13:39
  • Above containts in script should I edit like this :: copy the newest file from AccrualPnLMTD and rename it to AccrualMTD.csv call :copyAndRename "%Sourefolder%" "%TargetFolder%\AccrualMTD.csv" – niki niki May 29 '13 at 13:39
  • I've merged the two sets of code in the answer. It is untested. – foxidrive May 29 '13 at 14:05
  • it's not working, I believe 4th line should be remore. we'll define targat path in popup – niki niki May 30 '13 at 07:44
0

Excuse me. Your question is not clear. I assume that you want to copy and rename the 10 given files but not with the fixed paths given in the program, but with variable paths given when the program run. If this is correct, the program must get first the Target path (only one) and then the source path for each one of the files.

The Batch file below is a preliminary version that achieve previous process. If this solution is what you want, then the "browsing popup" part for the paths may be added instead of the simple "set /P folder=Enter folder:" commands. Or perhaps this version is enough for you?

EDIT: I modified the solution below in order to include these new requests:

I have variable target path for diffrent clients like for client a path wil be F:\Financial\ClientA\Data\%DateFolder%\Final Reports..& for client B "F:\Financial\ClientB\Data\%DateFolder%\Final Reports"

same goes in source path like Client A path "F:\Financial\Data\Reports\Client A\AccruntPnLMTD ; for client B Path will be F:\Financial\Data\Reports\Client B\AccruntPnLMTD..file folder names (AccruntPnLMTD,AccruntPnLMTD..etc) will reman same for each clients

LAST EDIT: The Batch file below has been modified for the last time in accordance with the last paragraph in this answer: Browse the existent folders in the disk and pick one.

@if (@CodeSection == @Batch) @then


@echo off
setlocal

rem Activate the browsing pop-up and ask for TargetFolder
for /F "delims=" %%a in ('CScript //nologo //E:JScript "%~F0" "Select the Target folder"') do (
   set TargetFolder=%%a
)

rem Activate the browsing pop-up and ask for SourceFolder
for /F "delims=" %%a in ('CScript //nologo //E:JScript "%~F0" "Select the Source folder"') do (
   set ClientSourceFolder=%%a
)

rem Process the list of "sourceFolder=fileName" pairs
for %%a in ("AccruntPnLMTD=PNL" "AccountPnlMTD=AC" "ExpensesMTD=EXPMTD" "ExpensesYTD=EXPYTD" "AccrualPnLYTD=PNLYTD"
            "AccountYTD=ACYTD" "BalanceMTD=BSMTD" "BalanceYTD=BSYTD" "FinancialStmtMTD=FSMTD" "FinancialStmtYTD=FSYTD"
           ) do (
   rem copy the newest file from sourceFolder and rename it to fileName.csv
   for /F "tokens=1,2 delims==" %%b in (%%a) do (
      call :copyAndRename "%%b" "%%c"
   )
)

:: Done
goto :eof

:copyAndRename
set SourceFolder=%ClientSourceFolder%\%~1
set TargetFile=%TargetFolder%\%~2.csv

:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%SourceFolder%"') do set 

"NewestFile=%%F"

:: copy and rename it to the target
copy "%SourceFolder%\%NewestFile%" "%TargetFile%"

:: Done with this subroutine
goto :eof


@end


// JScript section

// Creates a dialog box that enables the user to select a folder.
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774065(v=vs.85).aspx

var shl = new ActiveXObject("Shell.Application");
var folder = shl.BrowseForFolder(0, WScript.Arguments(0), 0, 0);
WScript.Stdout.WriteLine(folder ? folder.self.path : "");

In this new solution you may SELECT the desired client via the parameter of the Batch file. For example, if the Batch file is called example.bat, use this command for ClientA:

example.bat ClientA

You must note that BROWSING FOR A FOLDER is an interactive operation that present a pop-up window with all existent folders and allows you to choose one of them.

EDIT: Some explanations added

It seems that there is a confusion here. In your question you show as examples of target and source folders these ones:

set TargetFolder=F:\Financial\Data\%DateFolder%\Final Reports

:: copy the newest file from AccruntPnLMTD and rename it to PNL.csv
call :copyAndRename "F:\Financial\Data\Reports\AccruntPnLMTD"

However, in posterior comments you said:

I have variable target path for diffrent clients like for client a path wil be 
F:\Financial\ClientA\Data\%DateFolder%\Final Reports..& for client B
F:\Financial\ClientB\Data\%DateFolder%\Final Reports

same goes in source path like Client A path
F:\Financial\Data\Reports\Client A\AccruntPnLMTD ; for client B Path will be
F:\Financial\Data\Reports\Client B\AccruntPnLMTD..
file folder names (AccruntPnLMTD,AccruntPnLMTD..etc) will reman same for each clients

You must realize that two previous forms are entirely different: in the first one the folder path is constant, but in the second one the folder path must be changed for each client. A Batch file solution is always designed with fixed requirements. This point is not clear in your answer nor in your comments, so I assumed certain details in order to write a Batch solution. I think there are two ways to solve this problem, depending of what the problem is:

1- Select the appropriate folders for each client: in this case I assumed that path folders have this form:

Target Folder is formed by "F:\Financial\" followed by a variable part that select each client, followed by "\Data\%DateFolder%\Final Reports".

Source path is formed by "F:\Financial\Data\Reports\" followed by a variable part that select each client, followed by each one of the 10 different folders (AccruntPnLMTD,AccruntPnLMTD..etc).

If this is the problem, then my solution above solve it. You just need to place the desired folder name as parameter of the Batch file. For example, if the name of the folder for client a is "ClientA", execute this command:

nameOfTheBatchFile ClientA

If the name of the folder for client B is "ClientB", execute this command:

nameOfTheBatchFile ClientB

If the name of the folder have spaces, enclose it in quotes; for example, for "Any other client" execute this command:

nameOfTheBatchFile "Any other client"

However, your posterior comments and insistence on using terms like "browsing popup", "asking for the path", etc. makes me think that the previously explained problem is not the one you want to solve. There is another possibility:

2- Browse the existent folders in the disk and pick one: in this case when the program run it present a "browsing popup" window that give access to all folders in the disk and allows you to select anyone of them. Note that the browsing window can NOT restrict the browse for any particular name format; if you want that the selected folder have certain characteristics, like the data placed after "Data\" part be today's date in "MM.YYYY" format or any other restriction, this checking must be done after the user choose a folder, so the program will indicate that the selected folder was invalid and popup the browsing window again.

I encourage you to clearly explain your requirements. Please, modify your original question so anyone can understand the problem after read it and don't require to review all the comments in all answers.

Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Hi Aacini..Thx it's working good. that's what I was looking for. However, It would be great if I can define the target path and source path in a browsing popup...so I can do it fast..it's taking too much time – niki niki May 30 '13 at 08:42
  • I have variable target path for diffrent clients like for client a path wil be F:\Financial\ClientA\Data\%DateFolder%\Final Reports..& for client B "F:\Financial\ClientB\Data\%DateFolder%\Final Reports" – niki niki May 30 '13 at 09:34
  • same goes in source path like Client A path "F:\Financial\Data\Reports\Client A\AccruntPnLMTD ; for client B Path will be F:\Financial\Data\Reports\Client B\AccruntPnLMTD..file folder names (AccruntPnLMTD,AccruntPnLMTD..etc) will reman same for each clients. – niki niki May 30 '13 at 09:42
  • Whenever I run the script for client A I'll pick the path for respactive client paths..script does the same thing for each client bt location variables...that's why I want's to define the path by a browsing method. – niki niki May 30 '13 at 09:45
  • @nikiniki: See the edit in my answer. If you want to state further aclarations or add some points, please edit your original question (don't use comments) and post a new advice comment here. Be sure to clear if you really want to _browse_ for existent folders instead of _select_ different clients. – Aacini May 30 '13 at 12:57
  • I am not gatting..how can I use command for ClientA, do I need to rename my script name like macro.bat ClientA – niki niki May 30 '13 at 14:04
  • Yes, or use the same name; just insert ClientA (or ClientB, etc) after the batch file name. For example: `macro.bat ClientC` – Aacini May 30 '13 at 14:44
  • It is not asking for the path? do I have to create the macro for each client? – niki niki May 30 '13 at 16:12
  • Hi Aacini..you got me correct..we can do it both ways..but I want's to go with 2nd one...so I can salect the path as per variable requirments by only once script with browsing popup...please update the browsing commands in the script. – niki niki May 31 '13 at 10:57
  • Thx Aacini..I tried this but it's not come up with any output...However, it is asking both the path. – niki niki Jun 04 '13 at 07:11
  • Well, you must be careful when you select the folders in the browsing popup. Remember that the SourceFolder is where AccruntPnLMTD, AccruntPnLMTD... etc folders resides. You may insert several `echo` and `dir` commands in order to display the selected folders and its contents, so you may be sure that everything is OK (or identify the cause of the problem). – Aacini Jun 04 '13 at 10:26
  • Can I do this in Excel macro as well ...where I salect client and it works only for salected client. like I want to performe script for Client B so it shold work for client B... – niki niki Jun 14 '13 at 08:55