私の仕事はAccessデータベースを取得してExcelファイルを作成することですが、 OleDbが使用するExcelファイルを作成できないようです。
Excelファイル名は、ツールを実行しているエンジニアによって提供されます。Accessデータベースの各データテーブルは、Excelファイルのワークシートになります。
今のところ、乗り越えられないハードルが1つあります。Excelファイルが存在しないと、作成できません。
internal const string XL_FMT = "Provider=Microsoft.{0}.OLEDB.{1};Data Source={2};Mode=ReadWrite;Extended Properties=\"Excel {1};HDR={3};IMEX=1;\"";
internal DataTable tableNames;
internal OleDbConnection oleCon;
private string conStr;
public OleBase(string connectionString) {
conStr = connectionString;
// Using the debugger, conStr is:
// "Provider=Microsoft.ACE.OLEDB.12.0;" +
// "Data Source=C:\\Users\\cp-jpool\\Documents\\Ecat5.xlsx;" +
// "Mode=ReadWrite;Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=1;\""
object[] param = new object[] { null, null, null, "TABLE" };
oleCon = new OleDbConnection(conStr);
oleCon.Open();
tableNames = oleCon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, param);
}
Excelファイルが存在しない場合、呼び出すたびにOpen()
次のOleDbExceptionが発生します。
" MicrosoftAccessデータベースエンジンはオブジェクト'C:\ Users \ cp-jpool \ Documents \ Ecat5.xlsx'を見つけることができませんでした。オブジェクトが存在し、その名前とパス名を正しく入力していることを確認してください。' C:\の場合Users \ cp-jpool \ Documents \ Ecat5.xlsx'はローカルオブジェクトではありません。ネットワーク接続を確認するか、サーバー管理者に連絡してください。 "
それで、ファイルは存在しませんね?さて、私は自分を次のように変更して作成してみましたCTor()
:
public OleBase(string connectionString) {
conStr = connectionString;
object[] param = new object[] { null, null, null, "TABLE" };
oleCon = new OleDbConnection(conStr);
if (-1 < conStr.IndexOf(";IMEX=1;")) {
string dsString = "Data Source=";
int dsIndex = conStr.IndexOf(dsString);
string conSub = conStr.Substring(dsIndex + dsString.Length);
int firstCol = conSub.IndexOf(';');
string xlPath = conSub.Substring(0, firstCol);
if (!File.Exists(xlPath)) {
File.Create(xlPath);
}
}
oleCon.Open();
tableNames = oleCon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, param);
}
これで、このコードがOleDbConnectionのOpen()
メソッドを呼び出そうとすると、次のような異なるOleDbExceptionが発生します。
「MicrosoftAccessデータベースエンジンはファイルを開くことも書き込むこともできません」。すでに別のユーザーによって排他的に開かれているか、データを表示および書き込むためのアクセス許可が必要です。」
StreamWriterを使用してExcelファイルを作成し、基本的なヘッダーを追加してみました。
public OleBase(string connectionString) {
conStr = connectionString;
object[] param = new object[] { null, null, null, "TABLE" };
oleCon = new OleDbConnection(conStr);
if (-1 < conStr.IndexOf(";IMEX=1;")) {
string dsString = "Data Source=";
int dsIndex = conStr.IndexOf(dsString);
string conSub = conStr.Substring(dsIndex + dsString.Length);
int firstCol = conSub.IndexOf(';');
string xlPath = conSub.Substring(0, firstCol);
using (StreamWriter xls = new StreamWriter(xlPath, false, Encoding.UTF8)) {
xls.WriteLine("<?xml version=\"1.0\"?><?mso-application progid=\"Excel.Sheet\"?>");
xls.WriteLine("<ss:Workbook xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\" ");
xls.WriteLine("xmlns:o=\"urn:schemas-microsoft-com:office:office\" ");
xls.WriteLine("xmlns:x=\"urn:schemas-microsoft-com:office:excel\" ");
xls.WriteLine("xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\">");
xls.WriteLine("<ss:Styles>");
xls.WriteLine("<ss:Style ss:ID=\"Default\" ss:Name=\"Normal\"><ss:Alignment ss:Vertical=\"Bottom\"/><ss:Borders/><ss:Font/><ss:Interior/><ss:NumberFormat/><ss:Protection/></ss:Style>");
xls.WriteLine("<ss:Style ss:ID=\"BoldColumn\"><ss:Font x:Family=\"Swiss\" ss:Bold=\"1\"/></ss:Style>");
xls.WriteLine("<ss:Style ss:ID=\"StringLiteral\"><ss:NumberFormat ss:Format=\"@\"/></ss:Style>");
xls.WriteLine("<ss:Style ss:ID=\"Decimal\"><ss:NumberFormat ss:Format=\"0.0000\"/></ss:Style>");
xls.WriteLine("<ss:Style ss:ID=\"Integer\"><ss:NumberFormat ss:Format=\"0\"/></ss:Style>");
xls.WriteLine("<ss:Style ss:ID=\"DateLiteral\"><ss:NumberFormat ss:Format=\"mm/dd/yyyy;@\"/></ss:Style>");
xls.WriteLine("</ss:Styles>");
xls.WriteLine("</ss:Workbook>");
xls.Flush();
xls.Close();
}
}
oleCon.Open();
tableNames = oleCon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, param);
}
このコードは、さらに別のOleDbExceptionメッセージを生成しました。
「外部テーブルが予期された形式ではありません。」
ご覧のとおり、 OleDbConnectionにはファイルを作成するメソッドがないので、このExcelファイルを作成して使用できるようにするにはどうすればよいですか?