Access data macro get value from query (auto numbering)

社会主义新天地 提交于 2019-12-24 11:16:11

问题


Instead of the using the auto number in Access (sometimes produces duplicates) I've decided to generate my own numbers.

I am using the data macro Before Change but I'm not sure on how to run the query SELECT MAX(ID)+1 FROM MyTable and insert it into the ID field on each Insert.

I've messed around with the SetField, SetLocalVar, LookUpRecord actions but no luck so far.

EDIT: I've tried using DMAX in the expression as per example: https://www.599cd.com/tips/access/incrementing-your-own-counter/. This works when I add a row manually. However, I add rows from Excel VBA at which point this method stops working, generating the error, the function is not valid for expressions used in data macros


回答1:


You can only use very limited SQL statements in data macros. You can use queries, though.

Create a query (called QueryA), and enter SELECT MAX(ID)+1 As Expr1 FROM MyTable as the SQL

Then, you can use a data macro with the following structure:

If [IsInsert] Then
    Look Up A Record In      QueryA
          SetLocalVar 
                  Name = NewID
                  Expression = [QueryA].[Expr1]
    SetField
          Name = ID
          Value = NewID

The AXL is the following:

<?xml version="1.0" encoding="UTF-8"?>
<DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application">
   <DataMacro Event="BeforeChange">
      <Statements>
         <ConditionalBlock>
            <If>
               <Condition>[IsInsert]</Condition>
               <Statements>
                  <LookUpRecord>
                     <Data>
                        <Reference>QueryA</Reference>
                     </Data>
                     <Statements>
                        <Action Name="SetLocalVar">
                           <Argument Name="Name">NewID</Argument>
                           <Argument Name="Value">[QueryA].[Expr1]</Argument>
                        </Action>
                     </Statements>
                  </LookUpRecord>
                  <Action Name="SetField">
                     <Argument Name="Field">Field1</Argument>
                     <Argument Name="Value">[NewID]</Argument>
                  </Action>
               </Statements>
            </If>
         </ConditionalBlock>
      </Statements>
   </DataMacro>
</DataMacros>

You shouldn't use VBA functions or domain aggregates such as DMax in data macros, nor in the queries data macros are dependent upon. If you do, it can only be triggered from a running Access application, because these are only valid from within Access.


Alternatively, you can rewrite your SQL statement to be valid for data macros. This means: no aggregates, no calculations! But you can use ordering to get the maximum value:

If [IsInsert] Then
    Look Up A Record In      SELECT [MyTable].[ID] As [Expr1] FROM [MyTable] ORDER BY [MyTable].[ID] DESC
                      Alias A
          SetLocalVar 
                  Name = NewID
                  Expression = [A].[Expr1] + 1
    SetField
          Name = ID
          Value = NewID

The AXL is the following (which makes it easier to understand the limited SQL):

<?xml version="1.0" encoding="UTF-8"?>
<DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application">
   <DataMacro Event="BeforeChange">
      <Statements>
         <ConditionalBlock>
            <If>
               <Condition>[IsInsert]</Condition>
               <Statements>
                  <LookUpRecord>
                     <Data Alias="A">
                        <Query>
                           <References>
                              <Reference Source="MyTable" />
                           </References>
                           <Results>
                              <Property Source="MyTable" Name="ID" Alias="Expr1" />
                           </Results>
                           <Ordering>
                              <Order Direction="Descending" Source="MyTable" Name="ID" />
                           </Ordering>
                        </Query>
                     </Data>
                     <Statements>
                        <Action Name="SetLocalVar">
                           <Argument Name="Name">NewID</Argument>
                           <Argument Name="Value">[A].[Expr1]+1</Argument>
                        </Action>
                        <Action Name="SetField">
                           <Argument Name="Field">Field1</Argument>
                           <Argument Name="Value">[NewID]</Argument>
                        </Action>
                     </Statements>
                  </LookUpRecord>
               </Statements>
            </If>
         </ConditionalBlock>
      </Statements>
   </DataMacro>
</DataMacros>



回答2:


Replaces Access Autonumber LongInt Data Type Using simple Data Macro and one simple VBA function (see images x2)

Data Macro

VBA Code



来源:https://stackoverflow.com/questions/51873857/access-data-macro-get-value-from-query-auto-numbering

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!