I'm trying to import a semi colon delimited .csv file into an access database using the following code. I've set up an import specification which works called "Import-FACTS". and VBA can see the specification (by putting OLEacc.CurrentProject.ImportExportSpecifications(0) into the watch window.
Sub ImportFacts()
Dim OLEacc As Access.Application
Set OLEacc = GetObject("", "Access.Application")
OLEacc.OpenCurrentDatabase (ThisWorkbook.Path & "\" & "LargeData.accdb")
OLEacc.DoCmd.TransferText TransferType:=acImportDelim, _
SpecificationName:="Import-FACTS",_
TableName:="Facts",_
Filename:=ThisWorkbook.Path & "\Facts.csv",_
HasFieldNames:=False
End Sub
However I get the debug message:
Run-time error '3625' The text file specification "Import-Facts" does
not exist You cannot import export or link using the specification.
Any ideas?
Important note for imports
There is a problem with the text file specification as the name may not be the same that is displayed when you check your saved imports.
To know the true name, run the following SQL:
SELECT MSysIMEXSpecs.SpecName,
MSysIMEXColumns.FieldName,
MSysIMEXColumns.Start,
MSysIMEXColumns.Width,
MSysIMEXColumns.SkipColumn
FROM MSysIMEXColumns INNER JOIN
MSysIMEXSpecs ON MSysIMEXColumns.SpecID = MSysIMEXSpecs.SpecID
ORDER BY MSysIMEXSpecs.SpecName,
MSysIMEXColumns.Start,
MSysIMEXColumns.Width;
The SpecName field contains the right name you are looking for!
Related
Our office runs Arobat DC Pro and Excel 2016, we have been using the code below (scaled down version) in Excel VBA for years to save active Adobe PDF documents (that is, the open PDF doc that most recently had focus).
Since recently upgrading Arobat DC Pro to a newer version, the Acrobat PDDoc.Save method no longer works. It does not throw an error, it just doesn't save the active PDF.
I have had our IT dept. do an uninstall/reinstall of Acrobat PRO on a couple of computers but code still does not work.
Note, the Adobe Acrobat reference library is selected in VBA.
Any suggestions on how to fix?
Sub SaveActivePDF()
Dim AcroApp As Acrobat.CAcroApp
Dim PdDoc As Acrobat.CAcroPDDoc
Dim avdoc As Acrobat.CAcroAVDoc
Dim boolWasSaved As Boolean
Set AcroApp = CreateObject("AcroExch.App")
Set avdoc = AcroApp.GetActiveDoc
Set PdDoc = avdoc.GetPDDoc
DayTime = Format(Now, "yymmddhmmss")
Username = Environ("USERNAME")
PdfNewPath = "C:\Users\" & Username & "\Desktop\TEST PDF " & DayTime & ".pdf"
boolWasSaved = PDDoc.Save(PDSaveFull, PdfNewPath) '<-- NOT WORKING
If boolWasSaved = True Then
MsgBox "PDF WAS SAVED!"
Else: MsgBox "ERROR - PDF not saved"
End If
End Sub
For the record, access to the Acrobat library was blocked by sofware updates that changed default settings.
The issue was resolved as follows: Open any PDF > Edit > Preferences > Security (Enhanced) > ** UNCHECK ** check box "Enable Protected Mode at startup (Preview)" > exit all PDFs.
VBA idle->press "F2"-> search "AcroPDDoc"->locate its method "Save"
Function Save(nType As Integer, sFullPath As String) As Boolean
In Adobe's acrobatsdk_iacguide.pdf, description of Parameter nType is a little bit confusing. Not sure what integer is for PDSaveFull
nType is a logical OR of one or more of the following flags: PDSaveIncremental — Write changes only, not the complete file. This
will always result in a larger file, even if objects have been
deleted.
PDSaveFull — Write the entire file to the filename specified by
szFullPath.
PDSaveCopy — Write a copy of the file into the file specified by
szFullPath, but keep using the old file. This flag can only be
specified if PDSaveFull is also used.
PDSaveCollectGarbage — Remove unreferenced objects; this often reduces
the file size, and its usage is encouraged. This flag can only be
specified if PDSaveFull is also used.
PDSaveLinearized — Save the file optimized for the web, providing hint
tables. This allows the PDF file to be byte-served. This flag can only
be specified if PDSaveFull is also used.
Friends,
I currently am pulling data from an excel file located in OneDrive into my spreadsheet using the following source.
= Excel.Workbook(File.Contents("C:\Users\Bob Saggat\OneDrive - USS Enterprise\Prototype\InvestorsMasterProto.xlsm"), null, true)
I use the following code to successfully post data to files with different users from the OneDrive folder in VBA modules with the following code:
Workbooks.Open("C:\Users\" & Environ("username") & "\OneDrive - USS Enterprise\Prototype\OrdersMasterProto.xlsm")
I expected using Environ("username") in the Power Query Editor in the code for the source of the file to work.
= Excel.Workbook(File.Contents("C:\Users\" & Environ("username") & "\OneDrive - USS Enterprise\Prototype\InvestorsMasterProto.xlsm"), null, true)
When I do so I get the following error: Expression.Error: The name 'Environ' wasn't recognized. Make sure it's spelled correctly.
What is the solution here?
Some GoogleFu suggests I host the file on a SharePoint instead of in OneDrive but I have absolutely no experience in SharePoint and I presume there is a simple solution I am missing.
As always, your wisdom and kindness is greatly appreciated.
Thank You
--
Now, I call this module on load to find the username and put it into a named ranged. This works.
Sub GetUsernameForDataSource()
Dim OrderRunTemplate As Worksheet
Set OrderRunTemplate = ThisWorkbook.Worksheets("Order Run Template")
LocalUsername = Environ("username")
'May need to clear the CurrentUser named ranged first then add the user so it doesn't add multiple users
'Adding LocalUsername to named range to use as source in PowerQuery
ThisWorkbook.Names.Add Name:="CurrentUser", _
RefersTo:=LocalUsername
End Sub
Yet when I go into PowerQuery and enter the following
= Excel.Workbook(File.Contents("C:\Users\" & Excel.CurrentWorkbook(){[Name="CurentUser"]}[Content]{0}[Column1] & "\OneDrive - USS Enterprise\Prototype\InvestorsMasterProto.xlsm"), null, true)
I get the error:
Expression.Error: We couldn't find an Excel table named 'CurrentUser'.
Details:
CurrentUser
Any suggestions?
assuming you can get the value of Environ("username") into a named range such as abc, then you can read that named range in powerquery using
Excel.CurrentWorkbook(){[Name="abc"]}[Content]{0}[Column1]
and in your code as
= Excel.Workbook(File.Contents("C:\Users\" & Excel.CurrentWorkbook(){[Name="abc"]}[Content]{0}[Column1] & "\OneDrive - USS Enterprise\Prototype\InvestorsMasterProto.xlsm"), null, true)
I'm trying to import an Excel to Access DB, and some customer numbers cannot be imported due to Type Conversion Failure. It is 12 entries out of 66 thousand. Normally the customer number is a number, but these 12 are strings like ABCDEFT001. I tried setting the field of the table to Long Text or Short text, they are still not imported (only to ImportError table). Do you know what else I can try?
Thank you very much in advance!
P.S. I'm trying to import using DoCmd.TransferSpreadsheet
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "Inv level", "Path/to/file.xlsb", True, "Sheetname!"
This strategy links to the excel file, instead of directly importing it, and then selects data out of it and casts any fields that need it to the correct datatype.
Sub ImportFromExcel()
Dim pathToFile As String
Dim targetTableName As String
Dim sql As String
pathToFile = "C:\Path\To\File.xlsx"
targetTableName = "ImportResults"
'//create the link
DoCmd.TransferSpreadsheet acLink, _
acSpreadsheetTypeExcel12, _
targetTableName, _
pathToFile, _
True '//This part only if the excel file has field headers
'//import
sql = "SELECT Field1Name, CStr(CustNumber) AS CustNumber, Field3Name INTO NewImportTable FROM " & targetTableName
CurrentDb.Execute sql
'//remove the link
DoCmd.DeleteObject acTable, targetTableName
End Sub
***Two pitfalls of this code to be aware of:
1) You should delete any table with the name "NewImportTable" before running this code, or you'll get a "Table Already Exists" error.
2) If any errors happen in this Sub before you remove the link, you'll have an issue the next time it runs, as it will create a link called "ImportResults1" since "ImportResults" would still exist. The really scary thing is that no errors would be thrown here. It would create "ImportResults1" and then run your sql on "ImportResults"!!
I'm trying to open a CSV then use the SaveAs method to save it as an XLS. Also vice-versa in another script. I accidentally had the file format codes wrong before and was not getting this error. The CSV would in fact open. I accidentally had made the CSV format 2 (which is actually SYLK) and the XLS, 6 (which is actually CSV).
I've looked all over, and most of what I can find has to do with using an incorrect argument (which I have checked multiple times). The rest is for ASP, and suggests changing permissions in Component Services (which probably wouldn't be an issue anyway, since I can get the Open method to work with different formats).
So I'm at a loss as to how to proceed. If I can't even use the Open method, then I'm kind of stuck. If it was as simple as thee SaveAs method not working for this task, I could get around that. But I need to be able to open an XLS using the Open method (since I'm also trying to do XLS to CSV). CSV to XLS can be fixed another way, probably, since the Open method seems to work sometimes.
Anyway, my code for the CSV to XLS is below. The XLS to CSV is essentially identical to this. It just flips the format codes and uses different paths for the files.
strName = "MidCSVTemp.csv"
strSaveName = Month(Now) & "." & Day(Now) & "." & Year(Now) & ".xls"
strPath = "C:\Users\adam\Documents\" & strName
strSavePath = "C:\Users\adam\Documents\" & strSaveName
'Options for Workbook.Open
intUpdateLinks = 0
boolReadOnly = False
intFormat = 6
'Options for SaveAs
intFileFormat = 56
Set objExcel = CreateObject("Excel.Application")
Set objWorkBook = objExcel.Workbooks.Open(strPath,intUpdateLinks,boolReadOnly,intFormat)
Call objWorkBook.SaveAs(strSavePath,intFileFormat)
Call objWorkbook.Close
I think the issue is that you're using the Format parameter of the Workbooks.Open() method like it's the FileFormat parameter. It shouldn't be xlCSV (6), which is a FileFormat constant. According to the docs, Format should be one of the following values:
1 = Tabs
2 = Commas
3 = Spaces
4 = Semicolons
5 = Nothing
6 = Custom
Since you're passing a value of 6, it's expecting that you also include the Delimiter argument. And since you're not including it, you're getting an error.
You should be able to open a CSV without specifying the Format parameter (Excel seemed to guess the delimiter correctly for me without having to specify it). But, to be safe, pass a value of 2 for a comma-delimited (CSV) file.
intFormat = 2
Set objWorkBook = objExcel.Workbooks.Open(strPath,intUpdateLinks,boolReadOnly,intFormat)
Any suggestions for determining if a user-selected Excel file is the incorrect one? I am having the user select the excel file to be parsed and I want to refuse processing it if appears to be an incorrect format.
If the file being parsed has headings, then check some of the text.
Sub ImportXYZ()
' ... Code to import
If ActiveWorkbook.Worksheets("Sheet1").Range("A1") <> "XYZ" Then
MsgBox CStr(ActiveWorkbook.Name) & vbCr & _
"The file you selected does not contain XYZ data!" & vbCr & "Please try again."
' ... Code to reset
Call ImportXYZ
End If
' ... Code to process import
End Sub
Put a hidden version field or other string in the excel file and break the execution if the string does not match. Assuming of course that you have control over the file or template, from which the file is created.
As an alternative to putting a marker that identifies the right type of file inside a worksheet, you can also use Workbook properties. Create a Custom property "MyExcelFilesClassification", and give the property a value like "MyTypeOfWorkbook". When your code opens the file, check that the Property has the right value, with something like:
Office.DocumentProperties customProperties = workbook.CustomDocumentProperties as Office.DocumentProperties;
foreach (Office.DocumentProperty property in customProperties)
{
if (property.Name == "MyExcelFilesClassification")
{
string modelType = property.Value as string;
if (modelType == "MyTypeOfWorkbook")
{
// do something
}
}
}
This is C# code, but the VBA or VB syntax shouldn't be very different.