提问人:Joe 提问时间:2/2/2023 最后编辑:burnsiJoe 更新时间:2/3/2023 访问量:369
从 ASP.NET 或任何其他 Web 服务调用 ms Access 函数
Calling ms Access function from ASP.NET or any other Web Service
问:
我正在尝试从 Visual Studio 中的 ASP.NET Web 应用程序调用 Microsfot Access 函数。我能够连接到访问数据库并调用表和查询。
string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source = " + filePath;
string query = "Select * from table";
OleDbConnection connect = new OleDbConnection(connstring);
OleDbCommand command = new OleDbCommand(query, connect);
但是,我正在努力从 Asp.net 查找有关在访问数据库中调用函数的任何信息。
它甚至可以从 ms office 应用程序之外访问功能吗?Asp.net 或任何其他 Web 服务?
答:
您这里有 2 个单独的问题。
您想要从 Access 表中查询/提取数据。
这是“标准”公平的,您使用 oleDB 提供程序(在大多数情况下)。事实上,odbc 提供程序通常是更好的选择。但是,让我们把这个问题留到另一天。
但是,虽然您可以使用来自网站的访问数据文件?这并不是一个好的选择,因为您需要在 Web 服务器上安装访问数据引擎。这通常可能是一个真正的问题,因为托管提供商不会(甚至不允许)安装 Access 数据引擎。
注意:非常小心上面的词语选择:
我说的是访问数据引擎!!这就是 ms-access 使用的数据引擎。
但是,如果您想运行/调用/使用/消费VBA代码?
然后,您需要在该 Web 服务器上安装 ms-access。这是一场完全不同的球赛。虽然在 Web 服务器上安装 Access 数据引擎可能是一个挑战,但安装 Access 是一个完全不同的球类游戏。在大多数情况下,这种简单的事情是不允许的,也不会发生。
现在,您可以在开发人员计算机上执行此操作。
但是,存在大量问题。
首先:
您必须将 MS-Access 安装的位大小与 Web 服务器的位大小相匹配。默认情况下,您的 Web 服务器将以 x64 位运行。因此,这意味着您:
请确保已安装 ms-access x64 位。
或
强制项目和 Web 服务器以 x32 位运行。
接下来:
调用/使用/消费/运行/享受使用VBA代码例程?
然后,您不能只打开数据库(使用 oleDB 提供程序),但必须首先创建一个 Access 的 WHOLE RUNNING 实例。
当您创建该实例时,您还必须非常小心,因为在访问启动时,任何启动代码都将运行。(启动表单,VBA代码)。而且你无法控制当你这样做时会发生什么!
通常,最好创建数据库和代码的精简版本,并且仅包含您调用的 VBA 例程。然后,使用指向实际 accDB 数据文件的链接表。
创建MS-Access的整个运行实例后,就可以使用所有VBA代码例程。然而,这不是线程安全的,也不是一个伟大的主意。无论是 word、excel 还是 Access?尝试从 Web 服务器创建此类应用程序的运行实例通常是一个非常糟糕的主意。在这些应用程序中弹出的任何类型的“提示”都意味着您在这一点上注定要失败,因为从 Web 服务器和 .net 代码中,您无法单击或回答启动此类应用程序时经常出现的任何 UI 提示。
我要做的是获取VBA代码,创建一个新的 vb.net 类(独立)。粘贴该代码,然后将 VBA 代码转换为 vb.net 代码。他们非常接近。如果您构建一个记录集帮助程序类,那么您现在可以很容易地将相同的 VBA 代码(或非常接近相同)作为 vb.net 代码运行。
然后,编译该类,然后将该程序集添加到 c# Web 项目中,现在网站上运行的代码和逻辑相同。
以上是我推荐的方法。
我时间紧迫,但也许今天晚上,我会回来发布如何从 c# Web 应用程序调用/运行该 VBA 代码,但是虽然可能,但它不受支持,而且在生产 Web 服务器和站点中更糟?您真的没有太多选择来确保 ms-access 的完整工作版本已获得许可并安装在该 Web 服务器上。
我的意思是,你真的想走这条路吗,因为这是一个非常糟糕的设计决策选择。我建议您使用该代码,并在 .net 代码中复制逻辑。
在这里做出非常“糟糕”的设计决策是,真的很糟糕!
在最好的日子里,编写良好可靠的代码是一个巨大的挑战。那么,“如何”和“为什么”开发人员写出好的代码呢?
他们做出良好的设计决策,因此他们不会以不稳定的代码结束。这样的开发人员并不比你好,但他们的结果更好,因为他们首先避免选择导致设计不佳的道路。
我记得读过一本关于如何玩台球游戏的书。事实证明,那些更好的球员通常并不擅长射母球,但他们在击球后会做出更好的决定,将母球放在何处。
编写代码也大同小异。这并不是说你写了更好或更差的代码,而是你做出了更好或更差的设计决策,你必须忍受这些决策,然后随着时间的推移尝试调试+维护。换句话说,不要走上一条会导致代码运行、维护和选择非常困难的道路,这会降低代码库的可靠性。你可以很擅长编写代码,但如果这些代码是基于一个糟糕的设计决策,那么你仍然会很难使这些代码以可靠的方式工作。
编辑:所以,工作示例
因此,假设在 ms-access、VBA 中,有一个包含以下代码的代码模块:
Public Sub ConvertCity()
Dim rstData As DAO.Recordset
Dim strSQL As String
strSQL = "SELECT * FROM tblhotelsA where Active = True"
Set rstData = CurrentDb.OpenRecordset(strSQL)
Do While rstData.EOF = False
rstData.Edit
rstData!City = UCase(rstData!City)
rstData.Update
rstData.MoveNext
Loop
rstData.Close
End Sub
现在,上面只是一个示例,但上面的 VBA 从表中获取数据,并将 City 转换为大写。
现在,我们的 asp.net 标记(一个用于显示数据的按钮,以及一个用于运行上述VBA代码的按钮)。
所以,这个标记:
<asp:Button ID="cmdShowData" runat="server" Text="Show Access data" Width="173px"
CssClass="btn"
OnClick="cmdShowData_Click"/>
<asp:Button ID="cmdVBA" runat="server" Text="run Access VBA code"
CssClass="btn" style="margin-left:25px"
OnClick="cmdVBA_Click"
/>
<br />
<br />
<asp:GridView ID="GridView1" runat="server" CssClass="table table-hover"
width="50%" >
</asp:GridView>
而这段代码用Access数据加载GV
注意非常接近,我们没有启动访问,而只是打开数据库 - 使用数据。
protected void cmdShowData_Click(object sender, EventArgs e)
{
using (OleDbConnection conn = new OleDbConnection(Properties.Settings.Default.AccessDB))
{
string strSQL =
@"SELECT FirstName, LastName, City, HotelName, Description
FROM tblHotelsA
WHERE Active = True
ORDER BY HotelName";
using (OleDbCommand cmdSQL = new OleDbCommand(strSQL,conn))
{
DataTable rstData = new DataTable();
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
现在,我们的下一个标记按钮,即将在MS-Access中调用/运行/使用某些VBA代码的按钮。
该代码是这样的:
protected void cmdVBA_Click(object sender, EventArgs e)
{
Type MSAccess = Type.GetTypeFromProgID("Access.Application");
dynamic AccessInstance = Activator.CreateInstance(MSAccess);
// access is now running, open the database
string sFile = @"c:\test\test444.accdb";
AccessInstance.OpenCurrentDataBase(sFile);
// access is now running, call VBA routine
AccessInstance.run("ConvertCity"); // Call VBA in a public module
// AccessInstance.run("ConvertCity"); // Call some more VBA - walk the dog. do payroll
AccessInstance.Quit(); // you MUST quit/shut down Access
}
因此,当我们运行上面的网页时,我们看到/得到这个:
评论
OleDbCommand