Excel VBA Error #1004 – Excel cannot access the file

This is primarily a PeopleSoft nVision post – but it also pertains to Excel developers.  For those not familiar with it, nVision is a wrapper provided by Oracle/PeopleSoft whereby the Excel application can be used by PeopleSoft processes.  What gets produced is an Excel workbook.

Excel is installed on an application server, and is called via the nVision wrapper.  A number of our nVision layouts (Excel workbooks) have VBA macro code associated with them.

A shift in providing reports to consumers was recently made within the company.  Up til recently the reports were available from shares on the application server where nVision/Excel was running.  That’s been changed – the reports now have to be made available on a separate file server share.

And to make things both simpler as well as complex, the older style UNC path would no longer be allowed; instead all paths have to be DFS pointers.

Our users started running into random problems shortly after the change.  The common error was:

Error Source: Microsoft Office Excel.  Error #1004 – Description: Microsoft Office Excel cannot access the file ‘some file name’. There are several possible reasons:

The file name or path does not exist.

The file is being used by another program.

The workbook you are trying to save has the same name as a currently open workbook.

VBA Help Message # 1001004.

I was able to pin point what code was throwing the error, and it was in a section that does the following:

  1. Create a new workbook from a template
  2. Save the new workbook with a unique file name
  3. Copy some text from the source workbook
  4. Paste it into the new workbook
  5. Run some more vba to make the new worksheets pretty
  6. Save the new workbook and close it out

Rinse and repeat another several hundred times.  It took a couple of tries but from what I determined the error would always get thrown when attempting some action on the new (target) workbook.  And since that workbook was now being created in a remote share, DFS was the culprit.

That is a reasonable assumption based on how DFS works.  That’s not a topic for this post – if you want more Microsoft has an article here.  Note this line from the link – DFS requires Domain Name System (DNS) and Active Directory replication are working properly.

I see DNS and I think HTTP, network packets, domain controllers and RPC.  A far too complex environment for VBA to be operating in.

So to resolve the issue I changed where the work was being done.  Instead of saving the new workbook over the wire to the final destination and then doing more work to it via VBA; the work is back to being done in the same place the source workbook is.  That path is guaranteed by getting the ThisWorkbook.Path value of the source workbook.

So the above list is back to getting accomplished locally.  Once step 6 is complete there are two more items to the task list:

  • Use FIleSystemObject method CopyFile – and put a copy of the new workbook in the new reports share using DFS
  • Then user FileSystemObject method DeleteFile to get rid of the local copy of the new workbook.

No more random errors and the users are back to being happy.  And company policy is maintained.

Advertisements

Excel VBA – Execute macro code in another workbook

File this in the realm of why would I ever do that – then maybe after I explain you’ll see it makes sense.

I do this in situations where I’m ‘exploding’ data into reports.  And while this is more of a PeopleSoft nVision trick, I don’t see why it wouldn’t be useable in other applications.

Let me set up the scenario.  I have a chunk of data dumped into a workbook – I’m going to call it wbSource.  Inside that workbook is a macro that is going to run thru a worksheet and select a section of it based on some value in a column.

I copy and then paste the subset of data into another worksheet.  Nice, but I want it in another workbook.

Okay.  A bit of work here, I create another workbook and use it as a template.  That workbook has whatever base formatting I want along with macro code of its own.

Inside my wbSource I have the following code:

Private Function CreateTargetWorkbook() As Workbook

Dim wbTarget As Workbook
Set wbTarget = Workbooks.Add()
wbTarget.Activate
ActiveWorkbook.SaveAs Filename:=, FileFormat:=FileFormatNum
Set CreateTargetWorkbook = wbTarget
Set wbTarget = Nothing
End Function

The above function gets called this way:

Dim wbTarget As Workbook
Dim strRunCommand as String
Set wbTarget = CreateTargetWorkbook

I do my copy and paste code here…


strRunCommand = “‘” &  & “‘!Report_Main”
Application.Run strRunCommand

The italics make it a bit hard to read.  The string you create has a single quote surrounded by double quotes, the fully qualified path and file name, then another double quote, a single quote, an exclamation point, then the name of the macro that gets run followed by an ending double quote.  That gets added as a parameter to the Application.Run command.

Once the called macro code finishes control is passed back to the code in the source/caller workbook.

Now about why I go thru this.  First of all it follows good programming practice in that this follows the Principle of least privilege.  Code that knows how to section and subsection data is now separate from code that knows how to beautify a worksheet.  It also makes it easier to debug.  And later if changes are needed to the way the page is displayed, you don’t take a chance of breaking the code that chunks thru the data.  Vice versa if a change in terms of data occurs.

%d bloggers like this: