从 ASP.NET 或任何其他 Web 服务调用 ms Access 函数

Calling ms Access function from ASP.NET or any other Web Service

提问人:Joe 提问时间:2/2/2023 最后编辑:burnsiJoe 更新时间:2/3/2023 访问量:369

问:

我正在尝试从 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 服务?

C# asp.net Web 服务 ms-access

评论

0赞 Panagiotis Kanavos 2/2/2023
数据访问库是 ADO.NET 的,而不是 ASP.NET 的。 是一个 ADO.NET 类。Office 应用程序也使用 OLE DB 进行连接。OleDbCommand
1赞 jmcilhinney 2/2/2023
如果您谈论的是 Access 中的查询,那么我认为您可以像正确数据库中的存储过程一样调用它。如果你在谈论一个宏,那么那完全是另一回事。
0赞 Panagiotis Kanavos 2/2/2023
如何在 Access 本身中调用函数?你会写什么SQL查询?这也是您需要在此处使用的。
0赞 Steve 2/2/2023
也许您需要在 Access 数据库中添加一个“函数”示例,并解释当您调用它时,您希望在 NET 端看到什么
0赞 Joe 2/2/2023
我尝试调用的 ms access 中的函数会进行大量计算并将结果存储到 Access 本地表。我正在尝试调用访问计算函数并返回结果作为短期修复,直到可以在新的 Web 应用程序中重新设计访问应用程序(创建可能需要很长时间),我还需要传入参数来调用函数

答:

0赞 Albert D. Kallal 2/3/2023 #1

您这里有 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

}

因此,当我们运行上面的网页时,我们看到/得到这个:

enter image description here

评论

0赞 Joe 2/3/2023
非常感谢阿尔伯特为我所做的努力。我真的很感激。但我认为你对我的要求有点偏离了方向,我可能没有很好地解释我的要求。
0赞 Joe 2/3/2023
我有 ms access 数据库,其中包含大量信息,需要在新的基于 Web 的应用程序中重新设计,以将结果存储在 Oracle 表中。我们将不再使用 ms Access 作为前端应用程序。作为短期修复,我想在 ms access 中调用代码( 目前在 ms access 模块函数中进行了数千个计算,并且需要几个月的时间才能在不同的编程语言中创建新的计算,然后将结果存储在 Oracle 表中。
0赞 Joe 2/3/2023
我计划从 Visual Studio 调用 Web 服务进行 ms 访问,并可能使用 Json 返回结果。要从 ms access 获取计算,我需要传入可变部件号参数以获取要返回的计算 过去一周唯一的解决方案,我能找到的就是 OleDbConnection 从 visual studio 连接到 ms access 表。这不是我所需要的,因为我需要将参数传递给 ms access 并从调用函数中获得返回结果,这就是我正在努力解决的地方?因为我找不到任何方法来调用 ms 访问函数,请进行一些计算并返回结果
0赞 Albert D. Kallal 2/3/2023
示例代码运行该 vba,调用格式支持传递参数。但是,这不会返回值。但是,应该能够返回值。所以发布的示例调用了一个 vba sub。最好有 .net 的访问传递值。我会看看是否可以使用一个函数 - 不确定但应该可以
0赞 Joe 2/3/2023
再次感谢 Albert 的帮助,但是我收到 Type MSAccess = Type.GetTypeFromProgID(“Access.Application”) 的 Null 错误;动态 AccessInstance = Activator.CreateInstance(MSAccess);