在已打开的Access实例上通过Excel VBA运行Access查询

时间:2017-12-16 19:43:14

标签: excel vba excel-vba ms-access

我有一个列有Access查询名称的电子表格。我想通过Excel VBA在Access中运行这些查询,但是我想要处理已经打开的实例(和数据库),而不是打开新的Access实例。 我目前拥有的代码仅用于创建新实例:

Sub RunQueries()

Dim appAccess As Object
Set appAccess = CreateObject("Access.Application")
appAccess.Visible = True
appAccess.OpenCurrentDatabase "D:\Access\tysql.accdb", False

Dim QueryName As String

For i = 2 To Queries.Count + 1
    QueryName = Cells(i, 1).Value
    appAccess.DoCmd.OpenQuery QueryName
Next i

End Sub

我会很感激任何建议。

1 个答案:

答案 0 :(得分:1)

实际上,您使用的是MS Access的GUI端而不是其底层数据库引擎。考虑通过ADO的路由,其中​​涉及打开没有.accdb数据库到屏幕。实际上,您甚至不需要将MSAccess.exe GUI安装为MS Office程序!

package net.joshuad.hypnos.test;

import java.util.List;
import java.util.Locale;
import java.util.Set;

import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class CustomResizeExample extends Application {

    @SuppressWarnings("unchecked")
    private Parent getContent () {
        TableView <Locale> table = new TableView <>( FXCollections.observableArrayList( Locale.getAvailableLocales() ) );
        TableColumn <Locale, String> countryCode = new TableColumn <>( "CountryCode" );
        countryCode.setCellValueFactory( new PropertyValueFactory <>( "country" ) );
        TableColumn <Locale, String> language = new TableColumn <>( "Language" );
        language.setCellValueFactory( new PropertyValueFactory <>( "language" ) );
        table.getColumns().addAll( countryCode, language );

        TableColumn <Locale, Locale> local = new TableColumn <>( "Locale" );
        local.setCellValueFactory( c -> new SimpleObjectProperty <>( c.getValue() ) );

        table.getColumns().addAll( local );
        table.setColumnResizePolicy( new CustomResizePolicy() );

        BorderPane pane = new BorderPane( table );
        return pane;
    }
    @Override
    public void start ( Stage stage ) throws Exception {
        stage.setScene( new Scene( getContent(), 800, 400 ) );
        stage.show();
    }

    public static void main ( String[] args ) {
        launch ( args );
    }

}

@SuppressWarnings ( "rawtypes" ) 
class CustomResizePolicy implements Callback <TableView.ResizeFeatures, Boolean> {

    @SuppressWarnings("unchecked")
    @Override
    public Boolean call ( TableView.ResizeFeatures feature ) {

        TableView table = feature.getTable();
        List <TableColumn> columns = table.getVisibleLeafColumns();
        double widthAvailable = table.getWidth() - getScrollbarWidth ( table );


        double forEachColumn = widthAvailable / columns.size();

        for ( TableColumn column : columns ) {
            column.setMinWidth( forEachColumn );
            column.setMaxWidth( forEachColumn );
        }

        return true;

    }

    private double getScrollbarWidth ( TableView table ) {
        double scrollBarWidth = 0;
        Set <Node> nodes = table.lookupAll( ".scroll-bar" );
        for ( final Node node : nodes ) {
            if ( node instanceof ScrollBar ) {
                ScrollBar sb = (ScrollBar) node;
                if ( sb.getOrientation() == Orientation.VERTICAL ) {
                    if ( sb.isVisible() ) {
                        scrollBarWidth = sb.getWidth();
                    }
                }
            }
        }

        return scrollBarWidth;
    }
}

使用Access作为数据库引擎的美妙之处在于它可以移植到其他语言,如任何RDBMS,而不仅仅是Excel VBA。例如,在Python(我看到的是您的一个配置文件标签)中,您可以迭代csv(以该格式保存工作表)并在数据库中运行命名查询。

Dim conn As Object

Set conn = CreateObject("ADODB.Connection")

conn.Open "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=C:\Path\To\Database\File.accdb;"

Dim QueryName As String

For i = 2 To Queries.Count + 1
    QueryName = Cells(i, 1).Value
    conn.Execute QueryName
Next i

Set conn = Nothing