ダイアログ ボックスから Excel シートを読み取る SAP Business One アドオンに、以下のコードを使用しました。アドオンのテスト中に、ブレークポイントを配置しました
Thread.Sleep(1); // Wait a sec more
Visual Studio 2012 で。これにより、ダイアログ ボックスが開き、Excel ファイルを選択できるようになります。
- ダイアログは別のスレッドで実行する必要があります。
- ダイアログは、SAP クライアント ウィンドウの正しいインスタンスに対してモーダルである必要があります。
Visual Studio でのデバッグ/テスト中、アドオンは正常に動作し、マトリックスにコピーする Excel シートを選択できます。ただし、SAP に登録する .exe ファイル (実行可能ファイル) を使用して .ard を作成すると、ダイアログ ボックスで Excel ファイルを選択 ([OK] を押す) するとすぐにアドオンがハングします。
コードで何が間違っていますか?#
private void GetFileHeader()
{
using (GetFileNameClass oGetFileName = new GetFileNameClass())
{
oGetFileName.Filter = "Excel files (*.csv)|*.csv";
oGetFileName.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
Thread threadGetExcelFile = new Thread(new ThreadStart(oGetFileName.GetFileName));
threadGetExcelFile.SetApartmentState(ApartmentState.STA);
try
{
threadGetExcelFile.Start();
while (!threadGetExcelFile.IsAlive) ; // Wait for thread to get started
Thread.Sleep(1); // Wait a sec more
threadGetExcelFile.Join(); // Wait for thread to end
var fileName = string.Empty;
fileName = oGetFileName.FileName;
if (fileName != string.Empty)
{
string connString = "";
System.Data.DataTable dt = new System.Data.DataTable();
// Initialize connection string
connString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR=YES\"", fileName);
// Connect
OleDbConnection myConnection = new OleDbConnection(connString);
// Open connection if closed
if (myConnection.State != ConnectionState.Open)
myConnection.Open();
string fName = fileName;
fName = System.IO.Path.GetFileNameWithoutExtension(fName);
string sql = "SELECT * FROM [" + fName + "$] WHERE RecordKey IS NOT NULL";
OleDbCommand cmd = new OleDbCommand(sql, myConnection);
cmd.CommandType = CommandType.Text;
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
adapter.Fill(dt);
if (dt != null)
{
GetFileName クラス
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
namespace SBOPlugins.Enumerations
{
public enum eFileDialog { en_OpenFile = 0, en_SaveFile = 1 };
}
namespace CoreFrieght_Intraspeed
{
/// <summary>
/// Wrapper for OpenFileDialog
/// </summary>
public class GetFileNameClass : IDisposable
{
#region The class implements FileDialog for open in front of B1 window
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
System.Windows.Forms.FileDialog _oFileDialog;
// Properties
public string FileName
{
get { return _oFileDialog.FileName; }
set { _oFileDialog.FileName = value; }
}
public string[] FileNames
{
get { return _oFileDialog.FileNames; }
}
public string Filter
{
get { return _oFileDialog.Filter; }
set { _oFileDialog.Filter = value; }
}
public string InitialDirectory
{
get { return _oFileDialog.InitialDirectory; }
set { _oFileDialog.InitialDirectory = value; }
}
//// Constructor
//public GetFileNameClass()
//{
// _oFileDialog = new OpenFileDialog();
//}
// Constructor
public GetFileNameClass(SBOPlugins.Enumerations.eFileDialog dlg)
{
switch ((int)dlg)
{
case 0: _oFileDialog = new System.Windows.Forms.OpenFileDialog(); break;
case 1: _oFileDialog = new System.Windows.Forms.SaveFileDialog(); break;
default: throw new ApplicationException("GetFileNameClass Incorrect Parameter");
}
}
public GetFileNameClass()
: this(SBOPlugins.Enumerations.eFileDialog.en_OpenFile)
{
}
// Dispose
public void Dispose()
{
_oFileDialog.Dispose();
}
// Methods
public void GetFileName()
{
IntPtr ptr = GetForegroundWindow();
WindowWrapper oWindow = new WindowWrapper(ptr);
if (_oFileDialog.ShowDialog(oWindow) != System.Windows.Forms.DialogResult.OK)
{
_oFileDialog.FileName = string.Empty;
}
oWindow = null;
} // End of GetFileName
#endregion
#region WindowWrapper : System.Windows.Forms.IWin32Window
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
private IntPtr _hwnd;
// Property
public virtual IntPtr Handle
{
get { return _hwnd; }
}
// Constructor
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
}
#endregion
}
}
どんな助けでも感謝します。