I have a problem with a select file window popping up while updating a link to an excel file. I believe it's caused by the destination file being saved at the moment I refresh the link.
I have 2 computers. I open file "A" on the first one and file "B" on the other.
File "A" runs this macro:
application.enableevents = false
Do until(I set loop for couple minutes )
Range("a1").value = 1
save
range("a1).value = 2
save
Loop
File B runs this macro:
range("b2").value = (link to File A, cell "a1")
z = 1
do until (runs for couple minutes)
Cells(z,1).value = range("b2").value
z = z+1
loop
So basically the first file continuously changes the value of cell "a1" between 1 and 2, and saves each time, while the second one constantly refreshes the link and records the linked cell value.
It works for a few rounds, then a select file window pops up.
Exact formula for the cell containing link:
"='[" & BAZAO.Name & "]" & "ZMIANY'" & "!a1"
And in excel cell it looks like that:
„='[BWP 215.xlsm]ZMIANY'!a1”
The line of code that refreshes the link:
BAZA.UpdateLink (BAZAZ.Range("C3").Value)
BAZA - name of FILE B
BAZAZ.range("c3").value - contains address and name of file A
Range("b2").value = "='[" & BAZAO.Name & "]" & "ZMIANY'" & "!a1"
„='[BWP 215.xlsm]ZMIANY'!a1”
Can anyone tell me how to suppress this select file window, or if there is any other workaround?
I think it's happening because when opening the excel file, excel creates it's copy with generated name. When changes are being saved and the original file replaced, excel deletes original file first, and then puts a temporary file in its place changing name to the original one.
I guess the select file window pops up when my macros hit between that moments.
Is this the cause?
I think I have found a workaround.
Instead of using a cell to track file avaliability I have made the code to create file "inuse.txt" in the "file A" directory whenever its in use.
Then the "file B" just checks if that file is present through dir command
Related
I have a text file that is automatically generated from a machine. The machine writes the txt file in "chunks" (sorry I don't know the exact terminology). I need to pull data from this txt file, but I need the txt file to be finished before pulling data from it. I found a solution to verify that the machine has finished writing to the file... It is not as elegant as i had hoped, but seems to do the trick. Excel VBA opens a command prompt, the command prompt uses a Find command to find the string "End of Report"... This is basically one of the last lines of the txt file and pretty safe to assume the txt file is finished after this is found. This code runs in a loop 1000 times, every 10 seconds, until it finds this string or reaches 1000 tries...
The issue is that "result" returns some other characters besides just "End of Report" this is further complicated by the fact that I am attempting to run this on some csv files too... and "result" returns some additional characters also, but different from the ones returned from the txt files. For example, if I check the length of "result"... The length comes back as 43 on one file and 48 on another file... I think it is counting the file path + "End of Report" + a few more characters?
Anyways, I don't really need the "result"... I really only need a "true" / "false" if "Find" found "End of Report" or not... How can I accomplish this? Is there a different better way to do this? I am not familiar with command prompt programming.
Note: It is important that I search these files without opening them.
Sub test()
Dim SearchStr As String
Dim cmdLine As Object
Dim result As String
Dim FilePath As String
FilePath = "D:\test2.txt"
SearchStr = """End of Report"""
Set cmdLine = CreateObject("WScript.Shell")
result = cmdLine.Exec("%comspec% /C Find " & SearchStr & " " & Chr(34) & FilePath & Chr(34)).STDOut.ReadAll
Debug.Print (result)
End Sub
I am not really an expert in command line, but what I would do is export the result of the FIND command to a file, like here
Then I would check in your VBA code how many rows are in the file (either clean the file before, or check the number of rows before the export is done).
If the number of rows meets the criteria (probably 2 or more rows instead of 1), then you can set the flag to True.
My CSV file:
Product Code,Product Description,Net Weight,POR Number,BBE Info (DD/MM/YY)
0001450,Californian Whole Almonds,22.68kg,POR17195,21/11/19
Excel file, when importing the CSV file.
Question
I'd like to place the POR Number column to the left of Product Code. But when I refresh the data, it goes back to it's original place.
How can I load the CSV file into excel and choose which column loads up where? Without adjusting the CSV structure.
Here is a desired output when I refresh the CSV data:
Read the file line by line and use split to split the columns and then output the data where you need.
Use application.OnTime to run the code every minute.
Make NextRun a global date variable
sub split_csv()
File = FreeFile()
Open "csv.csv" For Input As #File
i = 2
While Not EOF(File)
Line Input #File, csvLine
cols = split(csvLine, ",")
range("A" & i).value = cols(1) ' and so on...
i = i+1
Wend
NextRun = Now + timevalue("00:01:00")
Application.OnTime EarliestTime:=NextRun, Procedure:="split_csv", Schedule:=True
end sub
To stop the code from running you have to use Application.OnTime EarliestTime:=NextRun, Procedure:="split_csv", Schedule:=False, I'll advice you to add that to workbook_close or if you forget to turn off the function it will open the workbook again and keep going.
you can use the integrated feature Get & Transform (Excel 2016) or earlier Version with the MS Power Query Add-in.
Go to Data > New Query > From File > From CSV
Select your csv file. Click Import.
A preview of the csv data will be shown. Click Edit.
Go to Home > Transform > Use First Row As Headers
Move the column you want with drog & drap over the column header
you may remove some columns with right click on the column header
Give it a try. The UI is very intuitive and you don't have to write any code for most transforming tasks.
The Applescript below works fine without any issues in Excel 2011. The script opens an Excel file, deletes a column and removes any "," or ";" from the Excel file and then saves it as a CSV file. The issue I'm running into in Excel 2016 is the last piece to save it as a CSV file after the manipulation. Nothing is saved and I don't get any errors.
tell application "Microsoft Excel"
activate
open theWorkbookFile #open the xls file
set theWorksheetname to name of worksheet 1 of active workbook
set theWorksheet to worksheet 1 of active workbook
activate object theWorksheet
tell application "System Events" to set visible of process "Microsoft Excel" to false
#Remove the first column
tell theWorksheet
delete range column 1 shift shift to left
try
##remove any "," and ";" from the product description and replace it with a " " instead.
replace (range "B:B" of worksheet "Sheet1") what "," replacement " "
replace (range "B:B" of worksheet "Sheet1") what ";" replacement " "
end try
end tell
#Set the temp csv file to the name of of the Excel sheet followed by -TMP.csv
set theFile to theWorksheetname & "-TMP" & ".csv" as text
save as theWorksheet filename theFile file format CSV file format with overwrite #save the file in csv format and overwrite if it exist
close active workbook saving no #close the csv file without prompting user to save again
end tell
I came across the same issue and managed to save as CSV kind of "manually", using AppleScript to do the user interaction that the user should do.
My code is below...
#here you choose the name to your CSV file
set fileName to "ClearD -" & (current date) as string
#here you should have your original .XLSX file name and address to open it further
set theDoc to ((path to desktop folder as text) & "ClearD-Data.xlsx") as string
tell application "Microsoft Excel"
activate
open file theDoc
delay 1
tell application "System Events"
keystroke "s" using {command down, shift down}
delay 0.3
tell front window of (first application process whose frontmost is true)
click pop up button 2 of sheet 1
delay 0.3
#we are doing this to select CSV in the dropdown menu
repeat 3 times
keystroke "c"
end repeat
key code 36 # hit return
delay 1
repeat 50 times # this will delete whatever the current file name is and put fileName instead
key code 123 using {shift down}
end repeat
delay 1
#this will type your file name
keystroke fileName
delay 1
click button "Save" of sheet 1
-- set uiElems to entire contents # I use this command only to see what is out there for me to use and troubleshoot
end tell
end tell
#now we are all good so we will close excel
close active workbook saving no
end tell
I have around 10,000 files all in one folder called "Z:\ContactLog\". The files are named "Contact_1.pdf", "Contact_2.pdf" etc. I also have an Access table with the file names listed in the first column and an associated group name in the second column. The group names are "Group1", Group2" etc.
I need help to write the VBA code to create a sub-folder for each group using the group name as the folder name, (e.g. "Z:\ContactLog\Group1\") and then move the files into the folders according to the group names listed against the file names in the table.
My research so far has found code for moving files based on the file name, but not based on a table field entry. Any help to get started with writing the VBA would be greatly appreciated. I am using Access 2010, but will do this in Excel if needed. Thank you.
I hope it isn't considered bad form to answer your own question, but I have just thought of and tested an answer using a completely different approach.
To achieve the goal I did the following:
Export the access table to Excel, so column A has the file name and column B has the name of the desired destination folder.
In column C use the formula...
=CONCATENATE("xcopy Z:\ContactLog\",A1,".pdf Z:\ContactLog\",B1,"\ /C")
Copy the formula downwards for all 10,000 entries
Copy and paste column C into a batch file
Run the batch file
Manually delete the source files
I have tried this on a small sample of the entries and it works perfectly. Xcopy will create the folders that don't exist. The switch "/C" will allow the batch to continue if there is an error (e.g. if the file does not exist).
Looks like your set, but I thought I would add an Access answer for the heck of it.
First back up the entire folder in question so you can revert incase something goes wrong. Next add a column in the file information table called FILE_MOVED so you can use it as a flag.
I've done this sort of thing a lot and have run into many issues like files moved, renamed, locked, etc. (If there's an error in the run, you'll end up with more errors on subsequent runs trying to move file's that have already been moved.) Be sure to update the FILE_MOVED col to 0 or null if you have to revert to original folder. So here's some code that should accomplish what you wanted:
Declare this in a Module:
Declare Function MoveFile Lib "kernel32" Alias "MoveFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String) As Long
Paste this into a Module:
Function OrganizeFiles() As Long
On Error GoTo ErrHandler
Dim rst As New ADODB.Recordset
Dim strFolderFrom As String, strFolderTo As String
Dim strPathFrom As String, strPathTo As String
rst.CursorLocation = adUseClient
rst.CursorType = adOpenForwardOnly
rst.LockType = adLockOptimistic
rst.Open "SELECT * FROM [YourTableName] WHERE nz(FILE_MOVED,0) = 0 ", CurrentProject.Connection
strFolderFrom = "Z:\ContactLog\" 'the main folder will always be the same
Do Until rst.EOF
'destination folder
strFolderTo = strFolderFrom & rst.Fields("[YourGroupCol]") & "\" 'destination folder can change
'make sure the destination folder is there; if not, then create it
If Dir(strFolderTo, vbDirectory) = "" Then MkDir strFolderTo
'get the source file path
strPathFrom = strBaseFolder & rst.Fields("[YourFileNameCol]")
'get the destination file path
strPathTo = strFolderTo & rst.Fields("[YourFileNameCol]")
Call MoveFile(strPathFrom, strPathTo)
'at this point the file should have been moved, so update the flag
rst.Fields("FILE_MOVED") = 1
rst.MoveNext
Loop
rst.Close
ErrHandler:
Set rst = Nothing
If err.Number <> 0 Then
MsgBox err.Description, vbExclamation, "Error " & err.Number
End If
End Function
This task and the my code is pretty basic but this kind of thing can become complicated when working with multiple source and destination folders or changing file names in addition to moving them.
I have about 400 excel files. I want to insert a column just before the first column in the existing file and then insert the name of the file into each row of that column.
I know a little bit of Applescript and based on that I wrote this script so that I can drop some files onto the script and it will execute the script on each one of those files.
I was wondering if someone could help me in completing the "TO DO" lines. Upon execution this script gives me dialogue boxes with the path of files that I drop on top. But the excel application throws an error dialogue box which says" Not enough memory". I tried this with only 2 excel files so it wasn't the number of files that caused the error.
Can someone please give me a hand with completing the TODO lines and give me an ide as to why Im getting the error. Thanks
property numFiles : 0
on open excelFiles
set fileNames to ""
tell application "Finder"
repeat with eachFile in excelFiles
--open document file eachFile
--tell application "Microsoft Excel"
--increment count
--save name of each file
set fileNames to fileNames & return & (POSIX path of eachFile)
--TO DO insert a column
--TO DO insert text in each column to the name of eachFile
--end tell
end repeat
display dialog fileNames
--display dialog "Ouch that hurt " & return & "You dropped " & (count excelFiles) & "files on me"
end tell
end open
on addFilePath(eachFile)
set fileNames to fileNames & (POSIX path of eachFile)
end addFilePath
Thanks a lot
I don't understand everything --> insert the name of the file into each row of that column | TO DO insert text in each column to the name of eachFile.
Here is the script, Updated :
on open excelFiles
set numFiles to count excelFiles
repeat with eachFile in excelFiles -- open each file in Excel
tell application "Microsoft Excel"
set tBook to open workbook workbook file name (eachFile as string)
set tName to name of tBook
insert into range column 1 of active sheet -- insert column
set lastCell to last cell of used range of active sheet -- get last cell from the used range
set value of range ("A1:A" & first row index of lastCell) of active sheet to tName --set first column's values to the file name
close tBook saving yes
end tell
end repeat
display dialog numFiles
end open
Edit : I forgot the error :
Not enough memory : This weird error seems to be : you call a handler without using my or tell me to) in a tell block application.
Use my like this : set x to my addFilePath(eachFile)
Also, a tell application "Microsoft Excel" block in the application Finder block is not recommended, this can cause unexpected errors.