How to read in Excel file in Win7 64bit? - 64-bit

I have a c# application that I have moved to a 64bit machine. This application reads in an Excel file for some data input. I would like to build this project as 64bit. Is there any way to have my program read in this file? I find it hard to believe that there is no way to use and Excel file as input into a 64bit app. I have installed Office 2010 64 bit as well as the 2010 Office System Driver Beta: Data Connectivity Components with no luck. I'm sure that I'm just missing something really simple.
thanks!!
Bill

The Jet OLEDB driver is not supported on Windows x64. Instead you could use the Office Interop library. Add reference to the Microsoft.Office.Interop.Excel assembly and try the following code:
using System;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;
class Program
{
static void Main()
{
var file = #"C:\work\test.xlsx";
var excel = new ApplicationClass();
var workbook = excel.Workbooks.Open(file);
var worksheet = (_Worksheet)workbook.Worksheets.Item[1];
// read the value of the first row, first column
var value = ((Range)worksheet.Cells[1, 1]).Value;
Console.WriteLine(value);
workbook.Close(false, file, null);
Marshal.ReleaseComObject(workbook);
}
}
Note that you will need to have Excel installed.

Related

VBA Run Time Error -2147221164(80040154) Class Not Registered

Good morning, afternoon, evening or whenever you are reading this.
That's the problem, I have a macro and two PC's
PC One (1): Which Run the macro perfectly.
PC Two (2) Which drops the error in the title.
The macro Connects SAPLogon, and PC Two breaks in this line:
Set Locx = CreateObject("SAP.LogonControl.1")
And here is the function:
Function SAPLogon() As Boolean
Set Lockx = CreateObject("SAP.LogonControl.1")
Set Conn = Lockx.NewConnection
Conn.Language = "S"
SAPLogon = Conn.logon(0, False)
Boths PC have the next exact vba references:
Visual Basic For Applications
Microsoft Excel 16.0 Object Library
OLE Automation
Microsoft Office 16.0 Object Library
Microsoft Forms 2.0 Object Library
SAP GUI Scripting API
But here is my big suspicion about why the macro doesn't run on PC Two:
PC One (1) Has Microsoft Office Personal Plus 2016 32-bit and PC Two Has Microsoft Office Personal Plus 2016 64-bit
The macro has been coded by another employee in 2002 (So I Think it's a 32-bit macro)
The question is:
Can 64 Bit Excel run 32 Bits Macros? How?
Thanks and Cheers
The issue here is that the SAP GUI is a 32bit application, and provides 32bit ActiveX controls for scripting in VBA. These will not work from 64bit Excel, however there is a solution. The comment above refers to another answer that explains more, but there are two solutions I'll summarise:
If you are able to install a new GUI then the latest version, 770 released February 2021 includes an optional install of 64bit NWRFC. This will install additional 64bit OCX controls that will work from 64bit Excel and VBA. (see https://stackoverflow.com/a/68906306/5087459).
If you need to use an older GUI then you will need to make a registry change using a surrogate as described in https://stackoverflow.com/a/65017544/5087459.

Calling Excel from VFP9 on 64-bit machine

I have a VFP9 application which generates Excel files using Automation, starting with :
**oExcel = CREATEOBJECT(“Excel.Application”)
oWorkbook = oExcel.Workbooks.Add()**
. . .
Excel 2013 is being used. The sheet is then populated, formatted and saved . This works fine on a Windows 7 32-bit machine. However on a Windows 7 64-bit machine, some instructions fail. In particular :
**oworkbook.SaveAs(<NewFilename>)**
fails with the message “Unable to get the SaveAs property of the workbook class”
As a work-around, I have created before creating the Excel object, and then called :
**oworkbook.Save ()**
This works. Have other users experienced this; are there any other limitations on the use of Excel from VFP when running on a 64-bit machine.
Thanks
Neither oWorkbook.SaveAs() nor oWorkbook.Save() have any problems on a 64 bit machine (I assume you meant windows (7/8/10) 64). Your problem should be something else.
I've experienced the identical problem but the issue turned out to be that the user had a different version of Excel than I did. It wasn't the 64 bit vs the 32 bit. I solved it by defining:
#define xlNormal 39
That set the target version of the workbook. Here is a page about the enumeration: https://msdn.microsoft.com/en-us/library/office/ff198017.aspx
I have also found that, in applications where I am saving up to like 50, that I have to open, set the save flag, do my work then say SaveAs.
Good luck with this :) Please consider closing this question. I think you get like two points for that.

Save Method of Application class failed when trying to save an Excel Document

I havea a method in Delphi that saves some data into a ExcelFile. The Program works fine for any kind of Excel except Excel 2013.
Here is the code
try
// If no instance of Word is running, try to Create a new Excel Object
ExcelApp := CreateOleObject('Excel.Application');
except
ShowMessage('Cannot start Excel/Excel not installed ?');
Exit;
end;
ExcelApp.DisplayAlerts := False;
ExcelApp.Workbooks.Add(xlWBatWorkSheet);
// fill the Excel file
ExcelApp.Visible := True;
// Save the Workbook
ExcelApp.save;
if not VarIsEmpty(ExcelApp) then begin
ExcelApp.DisplayAlerts := False; // Discard unsaved files....
ExcelApp.Quit;
end;
So As I said, this worked fine for Excel untill the 2013 Version. When I try to use this on a computer with Excel 2013 I get the error
Save Method of Application class failed.
Any Ideas why is this happening and any possible Workaround?
PS I tried with
ExcelApp.Workbooks[1].SaveAs('c:\test.xlsx', xlWBATWorksheet);
I also get an error :
SaveAS Method of Workbook class failed.
I also read that I could be that I don't have acces to save on that location, but i'm the administrator on the computer.
If I help the time of executing this operation takes a lot more time that It usually did in Excel 2010 or Excel 2007.
According to the documentation, the Excel Application object has no Save method. Use SaveAs from the Workbook object.
You are trying to save a file to the root directory of the system volume, and by default, that is secured so that standard user cannot create files in that location. Even though you are an administrator, UAC means that your process runs with a standard user token.
The other problem I see is that xlWBATWorksheet is not a file format constant. You mean to use xlOpenXMLWorkbook. This should be fine:
Workbook.SaveAs('c:\somedir\test.xlsx', xlOpenXMLWorkbook);
where you replace c:\somedir with some suitable path on your machine.
Switching to early bound COM might alleviate some of your travails but the answers can always be found in the documentation. You don't need to do this blind.
I haven't done any Microsoft Office automation myself but I do remember from the time that I still used Delphi 7 that when you installed it the installer actually asked you for which version of office do you wanna install the extensions for.
So I would gues that there are some differences in COM implementation that different versions of Microsoft Office use so it is posible that components your Delphi use for Microsoft Office Automation are not compatible with Office 2013.
May not be relevant but had same error message in VB6 (yes, 2016 and I still use it for odd things on Windows 10!) because the sheet was selected. Selected another object before saving and it worked.
You need to install KB2830391 HF460904 for Excel 2013 issue for AX 2009. Change in one sysExcel class on how the transfer/save are made!

SHGetSpecialFolderPath Error

I want to get the location of the program files folder, So i am using
SHGetSpecialFolderPath(NULL,Path_variable,CSIDL_PROGRAM_FILES,FALSE)
I don't see anything wrong here but I am getting the error
error C2065: 'CSIDL_PROGRAM_FILES' : undeclared identifier
I am using VC++ 6.0 and OS is WIN 7. What is the problem here ?. If I run the same code using Visual Studio 2005 , I am not getting any error.
This is alternative of your problem,You can use it
Try to read the registry entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir
At this position the path of the program files reside.
EDIT:
CRegKey key;
CString value = "ProgramFilesDir";
ULONG len = 255;
CString buffer;
long nError = key.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion",KEY_READ);
if(nError == ERROR_SUCCESS)
{
}
key.QueryStringValue(value,buffer.GetBufferSetLength(len),&len);
Now the buffer will contain the path
For more info see here
Could you please include entire code snippet you use to retrieve this folder?
I just tested it in the MFC application using VS 6.0 SP3 on XP Sp3 and it works like a charm.
For this to work on earlier systems you have to have IE 4 or later installed.
vikky:
Your code will not work in VS 6.0.
QueryStringValue member of the CRegKey does not exist.
Besides i think that using SHGetSpecialFolderPath should work.
Also, registry can change but the result of the SHGetSpecialFolderPath call will not.

Need a way to get the version # used by the msi installer at run time in c#, without knowing the location of the msi file used to install

I'm developing a scheme to automatically update my program from a central point. To assist me in this I need a way to get the version # of the msi file used to install the progarm at runtime, so I can compare the installed version with the latest version on the server (already solved this part) and decide whether or not to update. To be clear, I already have a way of opening up msi files using msi.dll and getting the version # out. The problem is one of bootstrapping. If the user installs the program for the very first time, how can my program know where to find the msi file (on the client)?
The solution can be as simple as the msi creating a text file with the version # in it when it runs. I'd like to avoid querying the registry if I can.
If I can't figure this out I'm going to have to take special care to keep the version #'s the same in the GUI project and also the MSI installer, and that thought annoys me.
Any thoughts?
I assume you want to get the ProductVersion property of the MSI.
You can do this fairly easily using COM.
Add a COM reference to "Microsoft Windows Installer Object Library" to your C# project.
Then try the following program:
namespace TestCS
{
using System;
using WindowsInstaller;
internal class Test
{
private static void Main(string[] args)
{
if (args.Length < 1)
{
return;
}
Console.WriteLine(GetMsiVersion(args[0]));
}
private static string GetMsiVersion(string installerPath)
{
Type t = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer inst = (Installer)Activator.CreateInstance(t);
Database d = inst.OpenDatabase(
installerPath,
MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);
View v = d.OpenView(
"SELECT * FROM Property WHERE Property = 'ProductVersion'");
v.Execute(null);
Record r = v.Fetch();
string result = r.get_StringData(2);
return result;
}
}
}
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall registry key contains ProductCode subkeys of installed programs. Control Panel's "Add/Remove Problems" and MSI Engine work with this branch.
Iterating through these subkeys you can find the GUID of your program (if you keep old value when changing version in Setup-and-Deployment project). Under that subkey 'DisplayVersion' string value will contain installed version (corresponds to 'Version' property in SnD project).
If you do change ProductCode when increasing Version number (as VisualStudio recommends), 'DisplayName' string may be useful for figuring out which subkey is representing your program, it corresponds to 'ProductName' property in SnD project.
Some programs may be listed in HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall when installed on a per-user basis (e.g. via ClickOnce).
On 64-bit systems there's HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall for 32-bit programs in addition to the original, which in that environment keeps track of 64-bit ones.

Resources