I'm trying to find all Access databases in a directory and Compact and Repair each without opening Access each time. I found the following article explaining how to find them and write to a file:
Batch file to find all Access Databases, but ideally I'd like to just find them and compact without writing to a file.
I have searched how to call the /compact command line functionality, but I don't know how to do it on the databases I find. Can a .bat file be written to do this? Something like:
#echo off
"C:\Program Files\Microsoft Office\Office14\MSACCESS.EXE" "C:\Databases\ /s" *.accdb /compact
Any help with the syntax is very much appreciated.
Consider using Access' dedicated CompactRepair method which you can run in VBA (inside an Access database or outside like in an Excel macro). The thing to note is Compact & Repair actually creates a copy of existing database and replaces it with original, so some file handling is needed.
VBA (inside MSAccess.exe)
Sub RunCompactDBs()
Dim path As String
Dim accfile As Variant
path = "C:\Databases\"
accfile = Dir(path & "*.accdb", vbDirectory)
Do While Len(accfile) > 0
bkfile = Replace(accfile, ".accdb", "_bk.accdb")
' CREATE COMPACTED BACKUP
Application.CompactRepair path & accfile, path & bkfile, False
' COPY TO ORIGINAL PATH
FileCopy path & bkfile, path & accfile
' DESTROY COMPACTED BACKUP
Kill path & bkfile
accfile = Dir
Loop
Set accApp = Nothing
End Sub
VBA (outside MSAccess.exe)
Sub RunCompactDBs()
Dim path As String
Dim accfile As Variant
Dim accApp As Object
Set accApp = CreateObject("Access.Application")
path = "C:\Databases\"
accfile = Dir(path & "*.accdb", vbDirectory)
Do While Len(accfile) > 0
bkfile = Replace(accfile, ".accdb", "_bk.accdb")
accApp.CompactRepair path & accfile, path & bkfile, False
FileCopy path & bkfile, path & accfile
Kill path & bkfile
accfile = Dir
Loop
Set accApp = Nothing
End Sub
And there's no reason to stick with VBA. Any language that can make a COM interface to the Access object library can run the compact and repair procedure like open-source languages:
Python
import os, glob, shutil
import win32com.client
# LAUNCH ACCESS APP
oApp = win32com.client.Dispatch("Access.Application")
for file in glob.glob("C:\\Databases\\*.accdb"):
bkfile = file.replace(".accdb", "_bk.accdb")
oApp.CompactRepair(file, bkfile, False)
shutil.copyfile(bkfile, file)
os.remove(bkfile)
oApp = None
R
library(RDCOMClient)
# LAUNCH ACCESS APP
oApp = COMCreate("Access.Application")
accfiles <- list.files(path="C:\\Databases\\", pattern="\\.accdb", full.names=TRUE)
for (file in accfiles){
bkfile = sub(".accdb", "_bk.accdb", file)
oApp$CompactRepair(file, bkfile, FALSE)
file.copy(bkfile, file, overwrite = TRUE)
file.remove(bkfile)
}
oApp <- NULL
gc()
PHP
# LAUNCH ACCESS APP
$acc = new COM("Access.Application", NULL, CP_UTF8) or Die ("Did not instantiate Access");
foreach (glob("C:\\Databases\\*.accdb") as $file) {
$bkfile = str_replace(".accdb", "_bk.accdb", $file);
$acc->Application->CompactRepair($file, $bkfile, false);
copy($bkfile, $file);
unlink($bkfile);
}
$acc = NULL;
unset($acc);
Related
I have an Access form with the drawing number D-A1ER-1378-1601-0 listed which is also stored in a file folder.
I use the code below to open the pdf drawing, which works fine.
Public Sub OpenDWG()
Dim strFile As String
Dim PathPDF As String
On Error GoTo Failure
PathPDF = DLookup("[FilePath]", "[SettingsDrawingFilePathTbl]", "ID = 4")
strFile = PathPDF & "\" & Screen.ActiveControl & ".pdf"
If Len(Dir(strFile)) Then
FollowHyperlink strFile
Else
MsgBox "No Document found for this Drawing Number, check Engineering Drawing Search File path in the Settings Tab and / drawing download files"
End If
Exit Sub
Failure:
MsgBox Err.Description
Err.Clear
End Sub
How do I adjust the strfile name
strFile = PathPDF & "\" & Screen.ActiveControl & ".pdf"
to get the form to open only the most recent file when a new version of the drawing is dropped into the folder. ie D-A1ER-1378-1601-0(2) will be the newest revision.
I would like to add a comment, but I don't have enough points ot comment.
I think that you can use the Dir function to get all files beginning with the same characters, or with wild cards, etc. I'll have to look into how exactly to do this. You could populate an array with these, and use code to scan the array to determine the latest file. Or you could populate a temporary table amd then use the table contents as the course to a combo box to have the user select the desired file, sorted with the latest one on top.
If I get a chance, I'll conjure up some sample code an post it.
I have found this code which allows me to drag and drop files onto to script icon and put them in a specified directory:
Const MyDestinationFolder = "C:\Temp\"
Const OverwriteExisting = True
Dim objFile,objFolder
Dim Arg
Set objFSO = CreateObject("Scripting.FileSystemObject")
If WScript.Arguments.Count > 0 Then
For Each Arg in Wscript.Arguments
Arg = Trim(Arg)
If InStr(Arg,".") Then
' Assume a File
Set objFile = objFSO.GetFile(Arg)
' Copy file to the Dest Folder using the same name
objFile.Copy MyDestinationFolder & objFile.Name,OverwriteExisting
Else
'Assume a Folder
Set objFolder = objFSO.GetFolder(Arg)
' Copy Folder to the Dest Folder
objFolder.Copy MyDestinationFolder, OverwriteExisting
End If
Next
End If
However I would like to make a script that runs and has a simple rectangle that says, drag and drop here. If this is at all possible, that would be great. Thanks!
You can add a GUI to VBScript programs by using "HTML Applications (HTAs)". Start your research here:
Introduction to HTML Applications (HTAs)
Extreme Makeover: Wrap Your Scripts Up in a GUI Interface
A Scriptomatic You Can Call Your Own
HTML Application
HTML Applications (HTAs)
Scripting Eye for the GUI Guy
and - of course
stackoverflow questions tagged hta
After second thoughts on "Drag & Drop", I found:
this claim and that .HTA (not tested)
So I have a "master" excel file that I need to populate with data from excel files in a directory. I just need to access each file and copy one line from the second sheet in each workbook and paste that into my master file without opening the excel files.
I'm not an expert at this but I can handle some intermediate macros. The most important thing I need is to be able to access each file one by one without opening them. I really need this so any help is appreciated! Thanks!
Edit...
So I've been trying to use the dir function to run through the directory with a loop, but I don't know how to move on from the first file. I saw this on a site, but for me the loop won't stop and it only accesses the first file in the directory.
Folder = "\\Drcs8570168\shasad\Test"
wbname = Dir(Folder & "\" & "*.xls")
Do While wbname <> ""
i = i + 1
ReDim Preserve wblist(1 To i)
wblist(i) = wbname
wbname = Dir(FolderName & "\" & "*.xls")
How does wbname move down the list of files?
You dont have to open the files (ADO may be an option, as is creating links with code, or using ExecuteExcel4Macro) but typically opening files with code is the most flexible and easiest approach.
Copy a range from a closed workbook (ADO)
ExecuteExcel4Macro
Links method
But why don't you want to open the files - is this really a hard constraint?
My code in Macro to loop through all sheets that are placed between two named sheets and copy their data to a consolidated file pulls all data from all sheets in each workbook in a folder together (by opening the files in the background).
It could easily be tailored to just row X of sheet 2 if you are happy with this process
I just want to point out: You don't strictly need VBA to get values from a closed workbook. You can use a formula such as:
='C:\MyPath\[MyBook.xls]Sheet1'!$A$3
You can implement this approach in VBA as well:
Dim rngDestinationCell As Range
Dim rngSourceCell As Range
Dim xlsPath As String
Dim xlsFilename As String
Dim sourceSheetName As String
Set rngDestinationCell = Cells(3,1) ' or Range("A3")
Set rngSourceCell = Cells(3,1)
xlsPath = "C:\MyPath"
xlsFilename = "MyBook.xls"
sourceSheetName = "Sheet1"
rngDestinationCell.Formula = "=" _
& "'" & xlsPath & "\[" & xlsFilename & "]" & sourceSheetName & "'!" _
& rngSourceCell.Address
The other answers present fine solutions as well, perhaps more elegant than this.
brettdj and paulsm4 answers are giving much information but I still wanted to add my 2 cents.
As iDevlop answered in this thread ( Copy data from another Workbook through VBA ), you can also use GetInfoFromClosedFile().
Some bits from my class-wrapper for Excel:
Dim wb As Excel.Workbook
Dim xlApp As Excel.Application
Set xlApp = New Excel.Application
xlApp.DisplayAlerts = False ''# prevents dialog boxes
xlApp.ScreenUpdating = False ''# prevents showing up
xlApp.EnableEvents = False ''# prevents all internal events even being fired
''# start your "reading from the files"-loop here
Set wb = xlApp.Workbooks.Add(sFilename) '' better than open, because it can read from files that are in use
''# read the cells you need...
''# [....]
wb.Close SaveChanges:=False ''# clean up workbook
''# end your "reading from the files"-loop here
''# after your're done with all files, properly clean up:
xlApp.Quit
Set xlApp = Nothing
Good luck!
At the start of your macro add
Application.ScreenUpdating = false
then at the end
Application.ScreenUpdating = True
and you won't see any files open as the macro performs its function.
My problem is that I need to open some excel files using VBA (for excel 2007) and extract the data. All the files I want to open are called "profit for January.xlsx", "profit for February.xlsx", and so on with only the month name changing, so I think I want to open a file called "profit for*". There is another file in the folder called "total revenue.xlsx" that I do not want to open.
If possible, I need the code to extract the data from the files in the folder, wherever the folder may be because I am sending this code to my colleagues to put into their own folders, which have the same file name formats etc but different paths.
I have the code to extract the data, which works, but it either imports all the data in the folder or none at all!
Any help on this would be much appreciated as I am an intern trying to get his foot in the door, and this would be quite a big break for me!
Further Information
So far I have the code below (I haven't included the dim's because I felt they may be unnecessary?), which I have drawn from other websites. I'm also finding that, in trying to open all the files in the folder, it is trying to open itself! If anyone could suggest how to improve this, I would be very grateful. I haven't been using VBA for very long, and have been finding this assignment quite tough!
The error box that comes up sometimes says that I need an 'object' for the variable sfilename, and I'm not sure how to do that without messing up another part of the code.
sub import data ()
ChDir ThisWorkbook.Path
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set sfolder = objFSO.GetFolder(ThisWorkbook.Path)
For Each sfilename In sfolder.Files
If sfilename <> "Total Revenue.xlsx" Then
Workbooks.Open Filename:= _
sfilename *'open the file*
Set sfilename = ActiveWorkbook *'set the file name as sfilename, so the single piece of code will work with the copy-loop*
b = Sheets.Count *'for the data-import loop*
Call ImportData *'call in the loop*
sfilename.Close *'close the file*
End If
Next
end sub
So far I have the code below (I haven't included the dim's because I felt they may be unnecessary?), which I have drawn from other websites. I'm also finding that, in trying to open all the files in the folder, it is trying to open itself! If anyone could suggest how to improve this, I would be very grateful. I haven't been using VBA for very long, and have been finding this assignment quite tough!
The error box that comes up sometimes says that I need an 'object' for the variable sfilename, and I'm not sure how to do that without messing up another part of the code.
Many thanks and kindest regards,
Mark
sub import data ()
ChDir ThisWorkbook.Path
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set sfolder = objFSO.GetFolder(ThisWorkbook.Path)
For Each sfilename In sfolder.Files
If sfilename <> "Total Revenue.xlsx" Then
Workbooks.Open Filename:= _
sfilename *'open the file*
Set sfilename = ActiveWorkbook *'set the file name as sfilename, so the single piece of code will work with the copy-loop*
b = Sheets.Count *'for the data-import loop*
Call ImportData *'call in the loop*
sfilename.Close *'close the file*
End If
Next
end sub
What are you using at the moment? For each file in folder?
Possibilities include
FileSystemObject
Dir
For i=1 to 12
Monthname(i)
EDIT
Sub import_data()
sPath = ThisWorkbook.Path
sTemplate = "\profit for qqq.xls"
For i = 1 To 12
sFileName = Replace(sTemplate, "qqq", MonthName(i))
''Just checking
If Dir(sPath & sFileName) <> "" Then
Workbooks.Open Filename:= _
sPath & sFileName
'open the file*
Set sFileName = ActiveWorkbook
'set the file name as sfilename, so the single
'piece of code will work with the copy-loop*
b = Sheets.Count
'*'for the data-import loop*
''Call ImportData
'*'call in the loop*
sFileName.Close
'*'close the file*
End If
Next
End Sub
I have multiple csv files with the same scheme, and I want to import them in one step. A solution could be to use the "import wizard", but I can only import one file with it. Oh, and it would be the best to work in msaccess2003. THX
The simplest solution is to start a dos-prompt, change to the directory where you have your files, and type:
type *.csv > allfiles.txt
If you do this often, you can create a batch-file that you can double-click from your desktop.
You can write a small program for importing see http://www.javaworld.com/javaworld/javaqa/2000-09/03-qa-0922-access.html for java JDBC conector to msaccess and since the import file is csv you can do this in no time...
There are other importing options for other languages
If all you want to do is drive the import with a list of files, you don't need a batch file. You can get the list of files using Dir():
Dim strCSVFileName As String
strCSVFileName = Dir("*.csv")
Do Until strCSVFileName = vbNullString
[import strCSVFileName]
strCSVFileName = Dir()
Loop
Of course, this assumes you're doing the import from within Access, but given your tags, that's the logical inference of your question.
This is an old thread, but it turned up when I searched for the issue. Hopefully this code helps someone address the same challenge. Builds / expands on the example David-W-Fenton offers, above.
I imported a file first, using the Wizard. Imported into a table named "bestTranscripts" and saved the import template as "BestImport" -- then used those values in the TransferText command.
Function ImportFiles()
On Error Resume Next
Dim cnn As New ADODB.Connection
Dim targetSet As New ADODB.Recordset
Dim sourceDirectoryName As String
Dim sourceFileName As String
sourceDirectoryName = "<path containing files>"
sourceFileName = Dir(sourceDirectoryName & "\*.txt")
Do Until sourceFileName = vbNullString
DoCmd.TransferText acImportDelim, "BestImport", "bestTranscripts", sourceFileName
sourceFileName = Dir()
Loop
End Function