{"id":68112,"date":"2011-10-04T22:25:31","date_gmt":"2011-10-04T15:25:31","guid":{"rendered":"https:\/\/bahtera.jp\/com-interface\/"},"modified":"2026-09-12T14:41:35","modified_gmt":"2026-09-12T07:41:35","slug":"com-interface","status":"publish","type":"post","link":"https:\/\/bahtera.jp\/en\/com-interface\/","title":{"rendered":"Details of Asprova's COM Interface and Plugin Extensions"},"content":{"rendered":"<p>The production scheduler Asprova provides a COM interface, allowing functionality to be extended with EXE files and plugins (DLL). This enables the retrieval of project objects deployed in memory and access to Asprova&#8217;s lower-level table objects.<\/p>\n<p>The Asprova main body is equipped with hooks to execute plugins at the timing of event occurrences. The plugin key, which serves as an access point representing this event, corresponds to the do_action or apply_filters hooks in WordPress.<\/p>\n\t\t\t\t<a href=\"https:\/\/bahtera.jp\/en\/indonesia-scheduler\/\" class=\"st-cardlink\" aria-label=\"Production Scheduler in Indonesia\">\r\n\t\t\t\t<div class=\"kanren st-cardbox\" >\r\n\t\t\t\t\t\t\t\t\t\t<dl class=\"clearfix\">\r\n\t\t\t\t\t\t<dt class=\"st-card-img\">\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/bahtera.jp\/wp-content\/uploads\/2025\/03\/indonesia-5-150x150.png\" class=\"attachment-st_thumb150 size-st_thumb150 wp-post-image\" alt=\"Structured diagram of production schedulers, PSI tables, and load planning in Indonesia\" srcset=\"https:\/\/bahtera.jp\/wp-content\/uploads\/2025\/03\/indonesia-5-150x150.png 150w, https:\/\/bahtera.jp\/wp-content\/uploads\/2025\/03\/indonesia-5-100x100.png 100w\" sizes=\"(max-width: 150px) 100vw, 150px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/dt>\r\n\t\t\t\t\t\t<dd>\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"st-cardbox-t\">Production Scheduler in Indonesia<\/p>\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"st-card-excerpt smanone\">\r\n\t\t\t\t\t\t\t\t\t<p>Production planning and load planning are closely related and require verification based on quantities. It is important to compare production quantities,\u2026<\/p>\n\t\t\t\t\t\t\t\t<\/div>\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p class=\"cardbox-more\">\u7d9a\u304d\u3092\u898b\u308b<\/p>\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/dd>\r\n\t\t\t\t\t<\/dl>\r\n\t\t\t\t<\/div>\r\n\t\t\t\t<\/a>\r\n\t\t\t\t\n<div class=\"article-point\" id=\"key-takeaways\">\n<h2 class=\"article-point-title\">What this article covers<\/h2>\n<ul>\n<li>Asprova can extend its functionality through the COM interface.<\/li>\n<li>DLL files must be placed in the same folder as Asprova&#8217;s EXE.<\/li>\n<li>The plugin key is similar to WordPress&#8217;s do_action hook.<\/li>\n<li>Asprova plugins are registered with four arguments.<\/li>\n<li>ADO is used to access the Jet Database Engine from VB.<\/li>\n<\/ul>\n<\/div>\n<p><script type=\"application\/ld+json\" id=\"wprestapi-ai-jsonld\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\/\/bahtera.jp\/en\/com-interface\/#article\",\"headline\":\"Details of Asprova's COM Interface and Plugin Extensions\",\"description\":\"Asprova can extend its functionality through the COM interface. DLL files must be placed in the same folder as Asprova's EXE. The plugin key is similar\u2026\",\"mainEntityOfPage\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/bahtera.jp\/en\/com-interface\/\"},\"inLanguage\":\"en\",\"datePublished\":\"2011-10-04T22:25:31\",\"dateModified\":\"2025-03-20T09:27:46\",\"author\":{\"@type\":\"Person\",\"name\":\"yamazou\"}},{\"@type\":\"ItemList\",\"@id\":\"https:\/\/bahtera.jp\/en\/com-interface\/#key-takeaways\",\"name\":\"What this article covers\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Asprova can extend its functionality through the COM interface.\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"DLL files must be placed in the same folder as Asprova's EXE.\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"The plugin key is similar to WordPress's do_action hook.\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Asprova plugins are registered with four arguments.\"},{\"@type\":\"ListItem\",\"position\":5,\"name\":\"ADO is used to access the Jet Database Engine from VB.\"}]}]}<\/script><\/p>\n<h2>What is the COM Interface<\/h2>\n<p>Asprova utilizes COM (Component Object Model) to expose its internal data and processing content. This allows for the addition of functions from plugins (ActiveX DLL files) and automation clients (Standard EXE files). Plugins operate by calling functions from Asprova, while automation clients access Asprova from external programs.<\/p>\n<p>DLL files are placed in the same folder as Asprova&#8217;s EXE and are automatically loaded at startup. DLLs are registered as internal commands of Asprova and can be incorporated into user-defined menus, allowing them to be called from Asprova. On the other hand, for EXE files, the active project can be obtained by specifying and opening the project file name.<\/p>\n<h2>DLL Placement Location<\/h2>\n<p>DLLs need to be placed in a specific location relative to the EXE that launches them. This ensures that the EXE correctly recognizes the DLL and can execute its functions properly. Below are the specific steps for placing DLLs.<\/p>\n<div class=\"graybox\">\n<div class=\"maruno\">\n<ol>\n<li>Place the EXE and DLL in the same directory. This allows the EXE to find the DLL directly.<\/li>\n<li>When launching the EXE, set the DLL&#8217;s directory as the current directory. This ensures the EXE prioritizes using the DLL within that directory.<\/li>\n<li>Place the DLL in the system32 directory. This directory is recognized as part of the Windows system, making it convenient if the DLL is widely used.<\/li>\n<li>Place the DLL in the Windows directory. This is also effective for using the DLL across the entire system.<\/li>\n<li>Set the directory where the DLL is located in the Path environment variable. This makes it easier for the system to recognize the DLL globally.<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<p class=\"field-note\" style=\"clear:both;width:100%;box-sizing:border-box;margin:18px 0 8px;padding:14px 16px 14px 18px;background:#fffaf3;border:1px solid #f0e0c8;border-left:5px solid #d97706;border-radius:6px;color:#3f3a32;line-height:1.75;\"><strong style=\"display:inline-block;margin-right:0.35em;color:#b45309;font-weight:700;\">Case:<\/strong> If a specific application cannot find the DLL, it may be due to insufficient settings in the Path environment variable. Proper configuration can resolve this issue.<\/p>\n<p class=\"field-generalization\" style=\"clear:both;width:100%;box-sizing:border-box;margin:0 0 22px;padding:10px 14px 10px 16px;background:#f5f9fc;border-left:4px solid #2f80ed;border-radius:0 6px 6px 0;color:#1f2937;line-height:1.7;\"><strong style=\"color:#1d4ed8;font-weight:700;\">Takeaway:<\/strong> Correctly setting the DLL placement location allows the EXE to smoothly recognize and operate with the DLL.<\/p>\n<h2>Reference Settings for Development Environment (Using Asprova Library from Within a Plugin)<\/h2>\n<p>Reference settings are saved within the project file (.vbp file) to utilize the type library of an ActiveX object without a GUI in the project. This allows access to Asprova&#8217;s library through the COM interface from the plugin (DLL compiled from the project file).<\/p>\n<p>By setting references, you can use the type of that object when declaring Dim variables or create instances with the new operator.<\/p>\n<div class=\"graybox\">\n<div class=\"maruno\">\n<ol>\n<li>Asprova Project Class Dim project As aslib.ASBProject<\/li>\n<li>List of objects related to the plugin key used in the extended plugin DLL Dim ArgList As ASPArgList<\/li>\n<li>Item Class Dim item As ASBItem<\/li>\n<\/ol><\/div>\n<\/p><\/div>\n<p>When referencing Asprova&#8217;s library from a plugin, register the following two Asprova class libraries from the development environment&#8217;s reference settings.<\/p>\n<div class=\"graybox\">\n<div class=\"maruno\">\n<ol>\n<li>As 1.1 Type Library<\/li>\n<li>AsPlugInManager 1.0 Type Library<\/li>\n<\/ol><\/div>\n<\/p><\/div>\n<h2>Structure of Plugin Project Files<\/h2>\n<p style=\"text-align: left;\">For plugins, functions called from Asprova are registered in the AutoRegistration method of the ASDefault class. If registered as a plugin in Asprova&#8217;s &#8220;Plugin Information,&#8221; the AutoRegistration function is automatically called upon Asprova startup and implemented within the project object.<\/p>\n<figure class=\"bahtera-article-figure\" style=\"clear:both;display:block;float:none;width:fit-content;max-width:100%;margin:12px auto;text-align:center;\"><img decoding=\"async\" alt=\"COM Port 2\" class=\"alignleft wp-image-6398 size-full\" height=\"276\" src=\"https:\/\/bahtera.jp\/wp-content\/uploads\/projectfile.jpg\" title=\"projectfile\" width=\"350\" srcset=\"https:\/\/bahtera.jp\/wp-content\/uploads\/projectfile.jpg 350w, https:\/\/bahtera.jp\/wp-content\/uploads\/projectfile-300x236.jpg 300w\" sizes=\"(max-width: 350px) 100vw, 350px\" \/><figcaption style=\"margin:6px 0 0;color:#666;font-size:0.9em;line-height:1.6;\">The ASDefault class is not required for Standard EXE (automation client).<\/figcaption><\/figure>\n<p>Plugins are registered by passing four arguments to the AddASPlugIn method of Asprova&#8217;s Plugin Manager (plugin registration function). This indicates, &#8220;I am a project called Factory, with a method called AddOverTime in the Overtime class (entry function), so please call it at the timing of the plugin key KeyHookGeneric.&#8221;<\/p>\n<div style=\"clear: both;\"><\/div>\n<h2>Mapping of Hooks and Functions Corresponding to Plugin Keys (Access Points)<\/h2>\n<p>Asprova provides hooks to execute plugins for specific events. These hooks function as access points representing each event and are called plugin keys. For example, KeyHookGeneric indicates &#8220;Add Command,&#8221; and executes the plugin when the added command is triggered.<\/p>\n<pre><code class=\"prettyprint linenums\">Option Explicit\r\n\r\nPublic Function AutoRegistration(plugInManager As ASPPlugInManager, module As ASPModule) As Boolean\r\n\r\n    'Set comments for this module\r\n    module.Comment = \"APS Extended Functionality PlugIns (VB)\"\r\n\r\n    'Define a variable to hold the plugin object\r\n    Dim plugIn As ASPPlugIn\r\n\r\n    ' ---------------------------------------------------------------------------------------------\r\n\r\n    'Call the plugin manager to register a new plugin. The method name is AddASPlugIn\r\n\r\n    ' 1st Param: Plugin display name\r\n    ' 2nd Param: ProgID representing the module and class where the plugin is implemented\r\n    ' 3rd Param: Entry function name (call name) of the plugin\r\n    ' 4th Param: Key name representing the context in which the plugin is used\r\n\r\n    '(1) Automatically calculate overtime and weekend work and set it in the calendar table\r\n    Set plugIn = plugInManager.AddASPlugIn(\"Incorporate Overtime into Weekend and Saturday Work\", \"Factory1.OverTime\", \"AddOverTime\", ASPlugInKeyName.KeyHookGeneric)\r\n\r\n    'Set comments, etc., for this plugin.\r\n\r\n    plugIn.Comment = \"Allocate overtime to 2 hours of weekday overtime and 2 shifts of Saturday work.\"\r\n\r\n    'Plugin call order (in case there are multiple plugins with the same plugin key)\r\n    plugIn.Order = 1\r\n\r\n    'Return True indicating that auto-registration was successful.\r\n    AutoRegistration = True\r\n\r\nEnd Function<\/code><\/pre>\n<p>Asprova automatically loads plugins at startup and displays the &#8220;display name of the entry function&#8221; in the internal command plugins. By calling Asprova&#8217;s plugin manager from within the plugin and passing four arguments, the plugin is registered.<\/p>\n<p><img decoding=\"async\" alt=\"COM Port 3\" class=\"aligncenter wp-image-6399\" height=\"538\" src=\"https:\/\/bahtera.jp\/wp-content\/uploads\/HookGeneric.jpg\" title=\"HookGeneric\" width=\"541\" srcset=\"https:\/\/bahtera.jp\/wp-content\/uploads\/HookGeneric.jpg 590w, https:\/\/bahtera.jp\/wp-content\/uploads\/HookGeneric-150x150.jpg 150w, https:\/\/bahtera.jp\/wp-content\/uploads\/HookGeneric-300x298.jpg 300w, https:\/\/bahtera.jp\/wp-content\/uploads\/HookGeneric-36x36.jpg 36w, https:\/\/bahtera.jp\/wp-content\/uploads\/HookGeneric-115x115.jpg 115w\" sizes=\"(max-width: 541px) 100vw, 541px\" \/><\/p>\n<h2>Same Concept as COM Port (communication port)<\/h2>\n<p>Although COM in COM port and COM interface are different, they share the commonality of being standard specifications for external interfaces. Both software and hardware have standardized interfaces (ports) for inputting and outputting data externally. For example, the ports for POP and SMTP servers or the ports for DB connections are TCP\/IP ports.<\/p>\n<p>Standard PCs are equipped with PS\/2 ports or USB ports for connecting peripherals like keyboards, as well as LAN ports (Ethernet ports).<\/p>\n<p>In software, methods for standard handling of data transmission and reception with external devices or communication networks are provided by the OS, and ports are used to identify communication partners.<\/p>\n<p>In Windows, a unified input\/output method called &#8220;COM port&#8221; is provided so that application software can uniformly access modems, printers, image scanners, etc. Application software can handle input and output simply by knowing which COM port the target device is connected to.<\/p>\n<p>For example, when connecting a USB barcode, COM13 is assigned, but since there are not physically 13 interfaces on the PC, COM13 is virtual. In network communication using TCP\/IP, &#8220;port numbers&#8221; from 0 to 65535 are used as auxiliary addresses under the IP address of communication devices or computers.<\/p>\n<p>This allows a single computer to provide multiple services or communicate with multiple computers simultaneously. When simply referring to a &#8220;port,&#8221; it often means a TCP\/IP port number.<\/p>\n<h2>Mapping Record Set Field Values to Crystal Report Field Definitions via ttx File<\/h2>\n<p>Export Asprova&#8217;s work table to Access to issue a work ticket. Crystal report 9 has a Parameter Field, allowing Passing Parameter from VB. However, when passing a Record Set, it automatically retrieves values from the fields and displays the report in a free ActiveX component viewer called Crystal Report Viewer.<\/p>\n<pre><code class=\"prettyprint linenums\">    CrRep.Database.SetDataSource rs, 3, 1\r\n\r\n    CRViewer91.ReportSource = CrRep\r\n\r\n    CRViewer91.ViewReport<\/code><\/pre>\n<p>The third argument 1 in this code represents the Table Number.<\/p>\n<pre><code class=\"prettyprint linenums\">    'Retrieve ORDERCOD of the selected combo\r\n\r\n    result = Combo1.List(Combo1.ListIndex)\r\n\r\n\r\n    'Passing parameter from VB6 to CR using CRAXDRT\r\n\r\n    Dim CrApp As CRAXDRT.Application\r\n\r\n    Dim CrRep As CRAXDRT.Report\r\n\r\n\r\n    'Retrieve record set of ORDERCOD from ORDERTBL\r\n\r\n    Dim conn As New ADODB.Connection\r\n\r\n    Dim rs As ADODB.Recordset\r\n\r\n\r\n    Dim mySQL As String\r\n\r\n\r\n    cn.Open _\r\n\r\n        \"Provider = Microsoft.Jet.OLEDB.4.0; \" &amp; _\r\n\r\n            \"Data Source = \" &amp; CurDir &amp; \"\\NNA.mdb\"\r\n\r\n\r\n    Set CrApp = New CRAXDRT.Application\r\n\r\n    Set CrRep = CrApp.OpenReport(App.Path &amp; \"\\reports\\TravelSheet.rpt\", &amp; _\r\n\r\n                    crOpenReportByTempCopy)\r\n\r\n\r\n    CrRep.DiscardSavedData\r\n\r\n\r\n    If result &lt;&gt; \"ALL\" Then\r\n\r\n        mySQL = \"SELECT * FROM OPERATIONTBL WHERE ORDERCOD='\" &amp; _\r\n\r\n            Combo1.Text &amp; \"' ORDER BY ORDERCOD\"\r\n\r\n    Else\r\n\r\n        mySQL = \"SELECT * FROM OPERATIONTBL ORDER BY ORDERCOD\"\r\n\r\n\r\n    End If\r\n\r\n    With rs\r\n\r\n        .ActiveConnection = cn\r\n\r\n        .CursorLocation = adUseServer\r\n\r\n        .CursorType = adOpenKeyset\r\n\r\n        .LockType = adLockOptimistic\r\n\r\n        .Properties(\"IRowsetIdentity\") = True\r\n\r\n\r\n        .Open mySQL\r\n\r\n    End With\r\n\r\n    CrRep.Database.SetDataSource rs, 3, 1\r\n\r\n    CRViewer91.ReportSource = CrRep\r\n\r\n    CRViewer91.ViewReport\r\n\r\n<\/code><\/pre>\n<p>However, development apps using non-standard components like Crystal Report Viewer on Win7 are likely to cause issues on XP, and crviewer9.dll may cause problems on older PCs. Therefore, downgrade to CR8.5 and modify the code as follows.<\/p>\n<pre><code class=\"prettyprint linenums\">Dim result As String\r\n\r\n\r\n    'Retrieve ORDERCOD of the selected combo box\r\n\r\n    result = Combo1.List(Combo1.ListIndex)\r\n\r\n\r\n    'Retrieve record set of ORDERCOD from ORDERTBL\r\n\r\n    Dim conn As New ADODB.Connection\r\n\r\n    Dim rs As ADODB.Recordset\r\n\r\n\r\n    Dim mySQL As String\r\n\r\n\r\n    cn.Open _\r\n\r\n        \"Provider = Microsoft.Jet.OLEDB.4.0; \" &amp; _\r\n\r\n            \"Data Source = \" &amp; CurDir &amp; \"\\DNN.mdb\"\r\n\r\n\r\n    If result &lt;&gt; \"ALL\" Then\r\n\r\n        mySQL = \"SELECT * FROM OPERATIONTBL WHERE ORDERCOD='\" &amp; _\r\n\r\n                    Combo1.Text &amp; \"' ORDER BY ORDERCOD\"\r\n\r\n\r\n    Else\r\n\r\n        mySQL = \"SELECT * FROM OPERATIONTBL ORDER BY ORDERCOD\"\r\n\r\n\r\n    End If\r\n\r\n\r\n    rs.Open mySQL, cn, adOpenKeyset, adLockOptimistic\r\n\r\n\r\n    With rptControl\r\n\r\n        .WindowTitle = \"Travel Sheet\"\r\n\r\n        .ReportFileName = App.Path &amp; \"\\Reports\\TravelSheet.rpt\"\r\n\r\n\r\n        .SetTablePrivateData 0, 3, rs\r\n\r\n        .WindowShowPrintBtn = True\r\n\r\n        .WindowShowPrintSetupBtn = True\r\n\r\n\r\n        .RetrieveDataFiles\r\n\r\n        .WindowState = crptMaximized\r\n\r\n        .Destination = crptToWindow\r\n\r\n        .Action = 1\r\n\r\n    End With<\/code><\/pre>\n<p>By specifying a ttx file (rpt.ttx) in the Report Expert of the CR file, the field values of the record set in the code are automatically mapped to the fields of the CR file.<\/p>\n<p><img decoding=\"async\" alt=\"reportexpert\" class=\"aligncenter wp-image-9326 size-full\" height=\"442\" src=\"https:\/\/bahtera.jp\/wp-content\/uploads\/reportexpert.jpg\" width=\"579\" srcset=\"https:\/\/bahtera.jp\/wp-content\/uploads\/reportexpert.jpg 579w, https:\/\/bahtera.jp\/wp-content\/uploads\/reportexpert-300x229.jpg 300w, https:\/\/bahtera.jp\/wp-content\/uploads\/reportexpert-100x76.jpg 100w, https:\/\/bahtera.jp\/wp-content\/uploads\/reportexpert-320x244.jpg 320w\" sizes=\"(max-width: 579px) 100vw, 579px\" \/><\/p>\n<p>Defining field names, attributes, and lengths in a tab-delimited ttx file is a classic method in Japan but still active in Indonesia.<\/p>\n<pre><code class=\"prettyprint linenums\">ORDERCOD\tstring\t100\r\n\r\nPROCNO\tnumber\r\n\r\nRESOURCE\tstring\t100\r\n\r\nITEM\tstring\t100\r\n\r\nQTY\tnumber\r\n\r\nSTARTDATE\tstring\t100\r\n\r\nENDDATE\tstring\t100\r\n\r\nWORKTIME\tstring\t100\r\n\r\nPARENTITEM\tstring\t100\r\n\r\nCLASS\tnumber<\/code><\/pre>\n<h2>Accessing Jet Database Engine from VB<\/h2>\n<p>To access the Jet Database Engine from VB, first add the &#8220;Microsoft ActiveX Data Objects 2.1 Library&#8221; in the reference settings.<\/p>\n<pre><code class=\"prettyprint linenums\">Dim conn As New ADODB.Connection\r\nDim rs As New ADODB.Recordset\r\n\r\nconn.Open _\r\n    \"Provider = Microsoft.Jet.OLEDB.4.0; \" &amp; _\r\n\"Data Source = C:\\Users\\Toshiba\\Desktop\\ERP\\VB\\LinkWithERP.mdb\"\r\n\r\n'DELETE\r\nDim query1 As String\r\nquery1 = \"DELETE * FROM ORDER_SOURCE\"\r\nrs.Open query1, cn, adOpenKeyset, adLockOptimistic\r\n\r\n'SELECT\r\nDim query2 As String\r\nquery2 = \"SELECT * FROM ORDER_SOURCE\"\r\nrs.Open query2, cn, adOpenKeyset, adLockOptimistic\r\n\r\nDo Until rs.EOF\r\n    X1 = rs!Order_Code\r\n    X2 = rs!Order_Item\r\n    X3 = rs!Order_Qty\r\n\r\n    rs.MoveNext\r\nLoop<\/code><\/pre>\n<p>ADO and ODBC are middleware used to utilize the Jet Database Engine (MDB). The MS-Access format MDB file is a file of the relational database engine developed by Microsoft, known as the Jet Database Engine, and serves as a container for storing data.<\/p>\n<p>This is a separate file independent of the Microsoft Access application and can be used even in environments where MS-Access is not installed.<\/p>\n<p>Even on a PC without MS-Access installed, it is possible to manipulate tables using ADO in Excel VBA, and you can download and open the Runtime from Microsoft&#8217;s site. It does not violate license restrictions. Runtime is a program that extracts only the execution function, omitting the application development function.<\/p>\n<div class=\"graybox\">\n<div class=\"maruck\">\n<ul>\n<li>http:\/\/www.microsoft.com\/ja-jp\/download\/details.aspx?id=4438<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<p>Just as Notepad is not the only application to edit text files, connecting to a DB (RDB) from a system is generally done via either ADO connection or ODBC connection. The differences between the two are as follows:<\/p>\n<div class=\"graybox\">\n<div class=\"maruck\">\n<ul>\n<li>ADO is an interface for operating OLEDB as an ActiveX control<\/li>\n<li>ODBC is an interface that provides RDB within OLEDB<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<p>Within OLEDB, there is an ODBC provider that connects to RDB, but developers can access OLEDB through the ADO interface. The method for generating connection objects and recordset objects involves using the CreateObject function to generate a new object variable and assigning a reference to the object to the object variable with Set.<\/p>\n<pre><code class=\"prettyprint linenums\">Dim conn As Variant\r\nDim rs As Variant\r\nSet conn = CreateObject(\"ADODB.Connection\")\r\nSet rs = CreateObject(\"ADODB.Recordset\")<\/code><\/pre>\n<p>Assigning object references using New involves creating a new object with New and assigning the reference of the object to the object variable with Set.<\/p>\n<pre><code class=\"prettyprint linenums\">Dim conn As ADODB.Connection\r\nDim rs As ADODB.Recordset\r\nSet conn = New ADODB.Connection\r\nSet rs = New ADODB.Recordset<\/code><\/pre>\n<h2>Accessing MySQL from VB<\/h2>\n<p>Even on a Windows 64-bit PC, since the development environment VB6 operates in 32-bit, you need to use the 32-bit version of the MySQL ODBC Connector.<\/p>\n<p>There is no issue with ADODB connections, but when performing a DSN connection, if you install the 32-bit version of the ODBC driver on a 64-bit version of Windows, the installed MySQL 5.1 driver may not appear when you launch the ODBC settings screen from the control panel.<\/p>\n<p>In this case, execute the following command from the command prompt to display the 32-bit ODBC Data Source Administrator screen and configure the DSN settings.<\/p>\n<div class=\"graybox\">\n<div class=\"maruck\">\n<ul>\n<li>%windir%\\SysWOW64\\odbcad32.exe<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<p>For DSN connections, use the following code to generate a connection object.<\/p>\n<pre><code class=\"prettyprint linenums\">'Generate connection object for MySQL 5.1 driver DSN\r\n\r\nDim conn As New ADODB.Connection\r\n\r\nDim rs As New ADODB.Recordset\r\n\r\nDim dsn As String\r\ndsn = \"dsn=xxx;uid=yyy;pwd=zzz\"\r\nconn.Open dsn\r\nconn.CursorLocation = 3<\/code><\/pre>\n<p>For ADODB connections, use the following code to generate a connection object.<\/p>\n<pre><code class=\"prettyprint linenums\">'Generate connection object for MySQL 5.1 driver ADO\r\n\r\nDim conn As New ADODB.Connection\r\n\r\nDim rs As ADODB.Recordset\r\n\r\nDim strConn, xServer, xDatabase, xUID, xPass As String\r\n\r\nIf conn.State = 0 Then\r\n\r\n    xServer = \"localhost\"\r\n\r\n    xDatabase = \"xxx\"\r\n\r\n    xUID = \"yyy\"\r\n\r\n    xPass = \"zzz\"\r\n\r\n    strConn = \"DRIVER={MySQL ODBC 5.1 Driver};SERVER=\" &amp; xServer &amp; _\r\n               \";PORT=3306\" &amp; _\r\n               \";DATABASE=\" &amp; xDatabase &amp; _\r\n               \";USER=\" &amp; xUID &amp; _\r\n               \";PASSWORD=\" &amp; xPass &amp; _\r\n               \";OPTION=3;\"\r\n    conn.Open strConn\r\n\r\nEnd If\r\n\r\n'DELETE\r\n\r\nDim query1 As String\r\n\r\nquery1 = \"DELETE * FROM ORDER_SOURCE\"\r\n\r\nrs.Open query1, strConn\r\n\r\n'SELECT\r\n\r\nDim query2 As String\r\n\r\nquery2 = \"SELECT * FROM ORDER_SOURCE\"\r\n\r\nrs.Open query2, strConn\r\n\r\nDo Until rs.EOF\r\n\r\n    X1 = rs!Order_Code\r\n\r\n    X2 = rs!Order_Item\r\n\r\n    X3 = rs!Order_Qty\r\n\r\n    rs.MoveNext\r\n\r\nLoop<\/code><\/pre>\n<h2>Accessing Excel from VB<\/h2>\n<p>To access Excel from VB, first add the Microsoft Excel 12.0 Object Library from the reference settings.<\/p>\n<pre><code class=\"prettyprint linenums\">'Excel related objects\r\n\r\nDim xlApp As Excel.Application\r\n\r\nDim xlBook As Excel.Workbook\r\n\r\nDim xlSheet As Excel.Worksheet\r\n\r\n\r\n\r\n'File name (full path)\r\n\r\nDim strFilename As String\r\n\r\nstrFilename = \"C:\\SO\\Delivery Schedule.xls\"\r\n\r\n\r\n\r\n'Sheet name\r\n\r\nDim strSheetName As String\r\n\r\nstrSheetName = \"Delivery Schedule\"\r\n\r\n\r\n\r\n'Create Application\r\n\r\nSet xlApp = CreateObject(\"Excel.Application\")\r\n\r\n\r\n\r\n'Open EXCEL\r\n\r\n'xlApp.Workbooks.Open FileName:=strFilename, UpdateLinks:=0\r\n\r\n\r\n\r\n'Create Workbook object\r\n\r\n'Set xlBook = xlApp.Workbooks(Dir(strFilename))\r\n\r\nSet xlBook = xlApp.Workbooks.Open(strFilename)\r\n\r\n\r\n\r\n'Create Worksheet object\r\n\r\nSet xlSheet = xlBook.Worksheets(strSheetName)\r\n\r\n\r\n\r\n'Get Worksheet data\r\n\r\nDim cnt As Integer\r\n\r\ncnt = 1\r\n\r\n\r\n\r\nDo\r\n\r\n    'ORDCOD can also be retrieved with Worksheets(\"Delivery Schedule\").Cells(cnt, 1).Text\r\n\r\n    ORDCOD = xlSheet.Cells(cnt, 1).Text\r\n\r\n    ORDITM = xlSheet.Cells(cnt, 2).Text\r\n\r\n    ORDQTY = xlSheet.Cells(cnt, 3).Text\r\n\r\n\r\n\r\n    cnt = cnt + 1\r\n\r\nLoop While ORDCOD &lt;&gt; \"\"<\/code><\/pre>\n<p>When creating a book object, if you assign the file name from a variable, you must remove the extension to retrieve it. However, if you assign a fixed path as a string, there is no problem. Use InStrRev to get the position of the period and exclude the extension.<\/p>\n<pre><code class=\"prettyprint linenums\">strFilename = CurDir &amp; \"\\data\\\" &amp; strFilename\r\n\r\n'Remove the extension (if not done, it will cause an error)\r\n\r\nstrFilename = Left(strFilename, InStrRev(strFilename, \".\") - 1)\r\n\r\n\r\n\r\nSet xlBook = xlApp.Workbooks.Open(strFilename)<\/code><\/pre>\n<p>The retrieval and addition of worksheet names are as follows.<\/p>\n<pre><code class=\"prettyprint linenums\">'Retrieve worksheet names\r\n\r\nj = 0\r\n\r\nFor Each ws In xlBook.Worksheets\r\n\r\n    sheetArry(j) = ws.Name\r\n\r\n    j = j + 1\r\n\r\nNext\r\n\r\n\r\n\r\n'Add worksheet 6\r\n\r\nSet xlSheet = xlBook.Worksheets.Add  'Add worksheet\r\n\r\nxlSheet.Name = \"New sheet\"<\/code><\/pre>\n<h2>Accessing Text Files (CSV) from VB<\/h2>\n<p>To access CSV files in VB, first add Microsoft Scripting Runtime from the reference settings. FileSystemObject is a component that makes it easy to handle the file system in Windows.<\/p>\n<pre><code class=\"prettyprint linenums\">'Generate DB connection object and recordset object\r\n\r\nDim conn As New ADODB.Connection\r\n\r\nDim rs As New ADODB.Recordset\r\n\r\n\r\n\r\n'Generate component object for handling CSV files\r\n\r\nDim objFSO As New Scripting.FileSystemObject\r\n\r\n\r\n\r\n'Connect to DB\r\n\r\nconn.Open _\r\n\r\n    \"Provider = Microsoft.Jet.OLEDB.4.0; \" &amp; _\r\n\r\n    \"Data Source = \" &amp; CurDir &amp; \"\\SO.mdb\"\r\n\r\n\r\n\r\n'Generate recordset with SELECT (empty)\r\n\r\nquery1 = \"SELECT * FROM ORDER_SOURCE\"\r\n\r\nrs.Open query1, conn, adOpenStatic, adLockOptimistic\r\n\r\n\r\n\r\n'Load data from CSV file into object\r\n\r\nSet objFile = objFSO.OpenTextFile(\"C:\\APS_ERP\\VB\\\" &amp; CSVNAME)\r\n\r\n\r\n\r\n'Read line by line and store in recordset\r\n\r\ncnt = 0\r\n\r\nDo Until objFile.AtEndOfStream\r\n\r\n    strMastflow = objFile.ReadLine\r\n\r\n    arrMastflow = Split(strMastflow, \",\")\r\n\r\n\r\n\r\n    rs.AddNew\r\n\r\n    rs(\"Order_Code\") = arrMastflow(0)\r\n\r\n    rs(\"Order_Item\") = arrMastflow(1)\r\n\r\n    rs(\"Order_Qty\") = arrMastflow(2)\r\n\r\n    rs.Update\r\n\r\n\r\n\r\n    cnt = cnt + 1\r\n\r\nLoop<\/code><\/pre>\n<p class=\"field-note\" style=\"clear:both;width:100%;box-sizing:border-box;margin:18px 0 8px;padding:14px 16px 14px 18px;background:#fffaf3;border:1px solid #f0e0c8;border-left:5px solid #d97706;border-radius:6px;color:#3f3a32;line-height:1.75;\"><strong style=\"display:inline-block;margin-right:0.35em;color:#b45309;font-weight:700;\">Case:<\/strong> By using this method, it is possible to directly read CSV files from VB and store them in the database. In particular, using ADODB.Connection and ADODB.Recordset allows for smooth integration with the database.<\/p>\n<p class=\"field-generalization\" style=\"clear:both;width:100%;box-sizing:border-box;margin:0 0 22px;padding:10px 14px 10px 16px;background:#f5f9fc;border-left:4px solid #2f80ed;border-radius:0 6px 6px 0;color:#1f2937;line-height:1.7;\"><strong style=\"color:#1d4ed8;font-weight:700;\">Takeaway:<\/strong> When handling CSV files in VB, it is important to utilize FileSystemObject and efficiently integrate with the database.<\/p>\n<h2>OLE DB Related Terms<\/h2>\n<p>The relationship between middleware and components until accessing the database through ADO is similar to the process of shipping cargo from a Shipper to a Consignee by sea.<\/p>\n<p><a href=\"https:\/\/bahtera.jp\/wp-content\/uploads\/oledb.jpg\"><img decoding=\"async\" alt=\"oledb\" class=\"aligncenter wp-image-3685 size-full\" height=\"304\" src=\"https:\/\/bahtera.jp\/wp-content\/uploads\/oledb.jpg\" width=\"615\" srcset=\"https:\/\/bahtera.jp\/wp-content\/uploads\/oledb.jpg 615w, https:\/\/bahtera.jp\/wp-content\/uploads\/oledb-300x148.jpg 300w\" sizes=\"(max-width: 615px) 100vw, 615px\" \/><\/a><\/p>\n<p>To access RDB, Excel, or Texfile (Consignee) from a development application program (Shipper), you request procedures from an intermediary (Forwarder) called the OLE DB data provider. However, since directly dealing with OLE DB is cumbersome, it is entrusted to ADO (Cargo Handler).<\/p>\n<div class=\"graybox\">\n<div class=\"maruck\">\n<ul>\n<li>OLE DB (Object Linking and Embedding DataBase) is a programming interface developed by Microsoft to access databases in a unified manner regardless of the type of database. For DB (Consignee), OLE DB is realized as a collection of COM components and can be used from any programming language. OLE DB is divided into &#8220;consumer&#8221; and &#8220;provider&#8221;; the consumer is the application accessing the data, and the provider is the software component implementing the interface, providing data to the consumer.<\/li>\n<li>The COM interface is a mechanism to expose internal data and processing content through COM (Component Object Model). It allows access to functions published by applications from plugins (ActiveX DLL files) or automation clients (Standard EXE files), enabling the development and publication of plugins.<\/li>\n<li>ADO (ActiveX Data Object) is a component for accessing databases via the OLE DB provider, making OLE DB usable in the form of ActiveX controls. Using ADO, you can directly manipulate table records from VB.<\/li>\n<li>ActiveX controls are an internet-enabled extension of the technology formerly known as OLE controls. ActiveX controls are downloaded from web servers over the network and used to add functionality to Internet Explorer.<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<p>Plugin DLLs are developed for adding functions, while extended interface DLLs are for modifying existing logic. The difference lies in whether you define a plugin key (KeyHookGeneric) in the AutoRegistration method of the AsDefault class or define an interface (IEIIFilterCalc ReplenishOrderLotSizing).<\/p>\n<h2>Differences Between Plugin Keys and Interfaces<\/h2>\n<p>When using plugins in Asprova, if you define a plugin key (KeyHookGeneric) within the AutoRegistration method of the AsDefault class, the entry function is called and executed when the corresponding event occurs.<\/p>\n<p>Similarly, if you define an interface (IEIIFilterCalc ReplenishOrderLotSizing) within the AutoRegistration method of the AsDefault class for EII (Extension Interface Implementation), the entry function is called when the corresponding event occurs.<\/p>\n<p>Interfaces are customized to have less overhead in calling than plugin keys, making them suitable for changes in logic that are frequently called, such as order expansion, automatic replenishment, and lot sizing. Plugin DLLs are developed to add functions, while extension interface DLLs are developed to modify existing logic.<\/p>\n<p><img decoding=\"async\" alt=\"Plugin DLL\" class=\"alignnone wp-image-51873 size-full\" height=\"588\" src=\"https:\/\/bahtera.jp\/wp-content\/uploads\/1-1208.png\" width=\"1067\" srcset=\"https:\/\/bahtera.jp\/wp-content\/uploads\/1-1208.png 1067w, https:\/\/bahtera.jp\/wp-content\/uploads\/1-1208-300x165.png 300w, https:\/\/bahtera.jp\/wp-content\/uploads\/1-1208-768x423.png 768w, https:\/\/bahtera.jp\/wp-content\/uploads\/1-1208-1024x564.png 1024w\" sizes=\"(max-width: 1067px) 100vw, 1067px\" \/><\/p>\n<p>Using an extension interface is more suitable than using a plugin key when you want to add an entry function called from events that frequently occur during rescheduling, due to the lower overhead in calling.<\/p>\n<h2>Extended Interface (DLL) for Changing Replenishment Order Lot Size<\/h2>\n<p>The lot size of a replenishment order is determined by &#8220;Manufacturing Lot Size MAX&#8221;, &#8220;Manufacturing Lot Size MIN&#8221;, and &#8220;Manufacturing Lot Size UNIT&#8221;. However, FilterCalcReplenishOrderLotSizing is called during the linking in the &#8220;Order Expansion&#8221; command, retrieves the following three objects to change (overwrite) the lot size of the replenishment order, and passes the result to ArgList.<\/p>\n<div class=\"graybox\">\n<div class=\"maruno\">\n<ol>\n<li>Array of replenishment items ArgAsObject(kArgItem)<\/li>\n<li>List of work input instructions for the initial process of the parent order ArgAsObject(kArgObjectList)<\/li>\n<li>List of lot sizes ArgAsSafeArray(kSafeArrayArgDouble)<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<h3>Lot Size<\/h3>\n<div class=\"graybox\">\n<div class=\"maruno\">\n<ol>\n<li>Lot size is automatic replenishment &#8220;Yes&#8221;<\/li>\n<li>Lot size is determined when the replenishment order is generated<\/li>\n<li>List of work input instructions (2D array) and list of work output instructions (items)<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<h3>Order Expansion Process<\/h3>\n<div class=\"graybox\">\n<div class=\"maruno\">\n<ol>\n<li>Generate the work (work input instructions and work output instructions) of the parent order. The parent order in the initial state is a sales order or registered order manufacturing order, and work input instructions and work output instructions are generated from the manufacturing BOM.<\/li>\n<li>In automatic replenishment, check whether the work input instructions of the parent order&#8217;s work are subject to linking. If the parent order is dated earlier than the inventory (absolute quantity), the work input instructions are not subject to linking, and manufacturing orders for the insufficient work input instructions are automatically generated. Generate manufacturing orders for the insufficient work input instructions (input items) of the parent order as child orders, and generate manufacturing orders for the insufficient work input instructions of the child orders as grandchild orders.<\/li>\n<li>In the first linking between orders, link sales orders, manufacturing orders, purchase orders, and inventory orders with automatic replenishment settings. Manufacturing orders without automatic replenishment settings (items connected by manufacturing BOM) are also linked.<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<h3>Example of Consolidating Pre-Processes in 7 Manufacturing Order Completions<\/h3>\n<div class=\"graybox\">\n<div class=\"maruno\">\n<ol>\n<li>In the first automatic replenishment, B1 is entered into item, and a list of B is entered into inst. Add the shortage quantity of input instruction B1 for work M4 (since there is no stock, RemainingQty is B itself) 7 times.<\/li>\n<li>In the second automatic replenishment, C is entered into item, and a list of A is entered into inst. Add the shortage quantity of input instruction C for work M2 7 times.<\/li>\n<li>Since the condition is inst.Operation.OperationMainRes.Code=&#8217;M4&#8242;, (2) is not executed.<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<p><img decoding=\"async\" alt=\"Plugin DLL\" class=\"alignnone wp-image-51877 size-full\" height=\"2582\" src=\"https:\/\/bahtera.jp\/wp-content\/uploads\/2-vert-1.jpg\" width=\"1067\" srcset=\"https:\/\/bahtera.jp\/wp-content\/uploads\/2-vert-1.jpg 1067w, https:\/\/bahtera.jp\/wp-content\/uploads\/2-vert-1-124x300.jpg 124w, https:\/\/bahtera.jp\/wp-content\/uploads\/2-vert-1-768x1858.jpg 768w, https:\/\/bahtera.jp\/wp-content\/uploads\/2-vert-1-423x1024.jpg 423w\" sizes=\"(max-width: 1067px) 100vw, 1067px\" \/><\/p>\n<p>To access each table in Asprova, it is necessary to go through the Asprova project object deployed in memory. The method of obtaining this project object differs between DLL and EXE. In the case of DLL, a list of objects related to the plugin key ASPArgList is loaded into the argument args, and the project object is obtained from here, whereas in the case of EXE, the active project is obtained from the document object that has loaded the specified project file.<\/p>\n<h2>In the Case of an Extension Plugin (DLL)<\/h2>\n<pre><code class=\"prettyprint linenums\">' (Definition and retrieval of objects within ASPArgList)\r\n\r\n'------------------------------------------------------------------\r\n\r\nPublic Function AddPersonPlan(args As ASPArgList) As TReturnType\r\n\r\n\r\n\r\n    ' Access objects of each APS table from the project object.\r\n\r\n    ' Retrieve the project object from the args interface.\r\n\r\n    ' Receive arguments by assigning the project object from the ASPAgrList object to a variable of type ASBProject.\r\n\r\n\r\n\r\n    Dim project As aslib.ASBProject\r\n\r\n    Set project = args.ArgAsObject(kArgProject)\r\n\r\n\r\n\r\n    ' Assign the RootObject from the project object to a variable of type ASORootObject.\r\n\r\n    Dim root As aslib.ASORootObject\r\n\r\n    Set root = project.RootObject\r\n\r\n\r\n\r\n    ' Assign the RootCalendar object from the project object to a variable of type ASBCalendar.\r\n\r\n    Dim calendarRoot As aslib.ASBCalendar\r\n\r\n    Set calendarRoot = project.RootCalendar\r\n\r\n\r\n\r\n    ' Assign the RootResource object from the project object to a variable of type ASBResource.\r\n\r\n    Dim resourceRoot As aslib.ASBResource\r\n\r\n    Set resourceRoot = project.RootResource\r\n\r\n\r\n\r\n    ' Assign the orderRoot object from the project object to a variable of type ASBOrder.\r\n\r\n    Dim orderRoot As aslib.ASBOrder\r\n\r\n    Set orderRoot = project.orderRoot\r\n\r\n\r\n\r\n    ' Assign the itemRoot object from the project object to a variable of type ASBItem.\r\n\r\n    Dim itemRoot As aslib.ASBItem\r\n\r\n    Set itemRoot = project.itemRoot\r\n\r\n\r\n\r\n    ' Define a variable for storing the property ID.\r\n\r\n    Dim propID1 As Long\r\n\r\n\r\n\r\n' (Access to the retrieved objects)\r\n\r\n'------------------------------------------------------------------\r\n\r\n    ' Number of children (records) in the calendar object.\r\n\r\n    calendarCount1 = calendarRoot.ChildCount\r\n\r\n\r\n\r\n    ' Use the root object to retrieve the property ID of the resource code.\r\n\r\n    propID1 = root.LookupPropID(\"Cal_Resource\")\r\n\r\n\r\n\r\n    ' Loop until the records end.\r\n\r\n    ' The argument for ChildAsCalendar starts from 1 (0 represents the last data).\r\n\r\n    For i = 1 To calendarCount1\r\n\r\n        ' Access the records.\r\n\r\n        Set calendar = calendarRoot.ChildAsCalendar(i)\r\n\r\n\r\n\r\n        ' Access the property value using the GetAsStr method. If the property is not an array value, set the second argument to 1.\r\n\r\n        res1 = calendar.GetAsStr(propID1, 1)\r\n\r\n    Next\r\n\r\n\r\n\r\nEnd Function<\/code><\/pre>\n<h2>In the Case of Standard EXE<\/h2>\n<p>When obtaining Asprova objects from an external EXE program, you need to load the project file into the document object and then retrieve the active project from there. The following steps illustrate this process.<\/p>\n<pre><code class=\"prettyprint linenums\">Private Sub Command1_Click()\r\n\r\n    '\u25a0\u25a0\u25a0Asprova Related Objects\u25a0\u25a0\u25a0\r\n\r\n    'Define Asprova Project Object\r\n\r\n    Dim m_pProject As ASBProject\r\n\r\n    Dim m_pDoc As ASFDocument\r\n\r\n    'Obtain Asprova Application\r\n\r\n    Dim app As ASFApplication\r\n\r\n    Set app = New ASFApplication\r\n\r\n    'Open Asprova Document by Specifying Name\r\n\r\n    Set m_pDoc = app.Deserialize(CurDir &amp; \"\\data.aru\")\r\n\r\n    'Retrieve Active Project from Document\r\n\r\n    Set m_pProject = m_pDoc.ActiveProject\r\n\r\n    '\u25a0\u25a0\u25a0Matching with End Order Items from Work Table\u25a0\u25a0\u25a0\r\n\r\n    'Obtain Work Object\r\n\r\n    Dim operation As ASBOperation\r\n\r\n    Dim operationList As ASOObjectList\r\n\r\n    Set operationList = m_pProject.GetOperationList(False)\r\n\r\n    'Obtain Root Object\r\n\r\n    Dim root As ASORootObject\r\n\r\n    Set root = m_pProject.RootObject\r\n\r\n    'Obtain propID (from root object)\r\n\r\n    propID1 = root.LookupPropID(\"Work_OperationOutMainItemQty\")\r\n\r\n    'Retrieve All Project Work for One-Time Matching\r\n\r\n    operationList.FilterByExprStr (\"WorkUser_MostRightOrderItem=='\" &amp; Left(Combo1.Text, 7) &amp; \"')\r\n\r\n    'Sort in Ascending Order of Production Start Date\r\n\r\n    operationList.SortByExprStr (\"Work_OperationProductionStartTime,a\")\r\n\r\n    Do\r\n\r\n        'Retrieve Data from List\r\n\r\n        Set operation = operationList.Object(i)\r\n\r\n        'Obtain Value\r\n\r\n        PrdQty = operation.GetAsStr(propID1, 1)\r\n\r\n        'Save Value\r\n\r\n        operation.SetAsStr propID1, 1, Text1.Text\r\n\r\n        i = i + 1\r\n\r\n    Loop While i &lt;= operationList.ObjectCount\r\n\r\n    '\u25a0\u25a0\u25a0Check Each Record in Resource Table\u25a0\u25a0\u25a0\r\n\r\n    'Define Resource Object\r\n\r\n    Dim RootResource As AsLib.ASBResource\r\n\r\n    Dim resource As AsLib.ASBResource\r\n\r\n    'Obtain Resource Root Object\r\n\r\n    Set RootResource = m_pProject.RootResource\r\n\r\n    'Obtain propID (from root object)\r\n\r\n    propID2 = root.LookupPropID(\"Res_Code\")\r\n\r\n    'Number of Records in Resource Table\r\n\r\n    ResourceCount = RootResource.ChildCount\r\n\r\n    For i = 1 To ResourceCount\r\n\r\n        Set resource = RootResource.ChildAsResource(i)\r\n\r\n        ResCode = resource.GetAsStr(propID2, 1)\r\n\r\n    Next i\r\n\r\n    '\u25a0\u25a0\u25a0Matching by Item Code from Item Table\u25a0\u25a0\u25a0\r\n\r\n    'Define Item Object\r\n\r\n    Dim RootItem As ASBItem\r\n\r\n    Dim Item As ASBItem\r\n\r\n    'Obtain Item Root Object\r\n\r\n    Set RootItem = m_pProject.RootItem\r\n\r\n    'Obtain Item Object\r\n\r\n    Set Item = RootItem.FindChild(Left(Combo1.Text, 7))\r\n\r\n    'Number of Matched Records in Item Table\r\n\r\n    ItemCount=Item.ChildCount\r\nEnd Sub<\/code><\/pre>\n<h2>Frequently Asked Questions | Asprova&#8217;s COM Interface<\/h2>\n<p>This article organizes frequently asked questions concisely according to its content.<\/p>\n<h3>What is Asprova&#8217;s COM Interface?<\/h3>\n<p>Asprova&#8217;s COM Interface is a mechanism that exposes internal data and processing content. This allows for the addition of functions from plugins and automation clients.<\/p>\n<h3>How are Asprova plugins registered?<\/h3>\n<p>Asprova plugins are registered using the AddASPlugIn method of the Plugin Manager. By passing four arguments to this method, the plugin is set to execute at specific events.<\/p>\n<h3>Where should DLL files be placed?<\/h3>\n<p>DLL files need to be placed in the same folder as Asprova&#8217;s EXE. This ensures that the EXE correctly recognizes the DLL and executes functions properly.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Asprova can enhance its capabilities using the COM interface and plugins. DLL files should be located in the same directory as the Asprova executable.<\/p>\n","protected":false},"author":2,"featured_media":104636,"parent":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[619],"tags":[],"class_list":["post-68112","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-production-scheduler"],"_links":{"self":[{"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/posts\/68112","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/comments?post=68112"}],"version-history":[{"count":1,"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/posts\/68112\/revisions"}],"predecessor-version":[{"id":102759,"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/posts\/68112\/revisions\/102759"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/media\/104636"}],"wp:attachment":[{"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/media?parent=68112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/categories?post=68112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bahtera.jp\/en\/wp-json\/wp\/v2\/tags?post=68112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}