DoCmd.RunSQLクエリの実行中にエラー3340クエリ ''が破損しています


83

Office 2010のWindows更新プログラムをインストールしからKB 4484127解決すると、WHERE句を含むクエリの実行中にエラーが発生します。

たとえば、次のクエリを実行します。

DoCmd.RunSQL "update users set uname= 'bob' where usercode=1"

このエラーの結果:

エラー番号= 3340クエリ ''が壊れています

問題アップデートは現在もインストールされています:

Microsoft Office 2010 Service Pack 2の更新448127を示すスクリーンショット

クエリを正常に実行するにはどうすればよいですか?この更新プログラムをアンインストールする必要がありますか?

回答:


92

概要

これは、2019年11月12日にリリースされたOfficeの更新によって引き起こされる既知のバグです。このバグは、Microsoftが現在サポートしているAccessのすべてのバージョン(Access 2010から365)に影響します。

このバグは修正されました。

  • C2R(クイック実行)バージョンのOfficeを使用している場合は、[ 今すぐ更新]を使用します
    • Access 2010 C2R:ビルド7243.5000で修正
    • Access 2013 C2R:ビルド5197.1000で修正
    • Access 2016 C2R:ビルド12130.20390で修正済み
    • Access 2019(v1910):ビルド12130.20390で修正済み
    • Access 2019(ボリュームライセンス):ビルド10353.20037で修正
    • Office 365 Monthly Channel:ビルド12130.20390で修正済み
    • Office 365半年:ビルド11328.20480で修正済み
    • Office 365半期延長:ビルド10730.20422で修正
    • Office 365半期ターゲット:ビルド11929.20494で修正済み
  • MSIバージョンのOfficeを使用している場合は、Officeバージョンに一致するアップデートをインストールしてください。これらのパッチはすべてMicrosoft Updateでリリースされているため、保留中のすべてのWindows Updateをインストールするだけで十分です。

これが最小限の再現例です。

  1. 新しいAccessデータベースを作成します。
  2. デフォルトのIDフィールドとLong Integerフィールド「myint」を使用して、新しい空のテーブル「Table1」を作成します。
  3. VBAエディターのイミディエイトウィンドウで次のコードを実行します。

    CurrentDb.Execute "UPDATE Table1 SET myint = 1 WHERE myint = 1"

予期される結果:ステートメントは正常に終了します。

バグのある更新プログラムの1つがインストールされた実際の結果:実行時エラー3340が発生します(「クエリ ''が破損しています」)。


関連リンク:


9
この投稿では、64ビットアクセスランタイムとOLEDBを使用して同じエラーが発生するようです。恐ろしいことに、これにより、Accessを使用してデータを格納する多くのアプリケーションが使用できなくなります。
エリックA

4
私はOffice 2013 32ビットでシステムをチェックしましたが、その特定のマシンでの更新のUUIDは90150000-006E-0409-0000-0000000FF1CE...で-0409-はありません-0407-
Gord Thompson

4
Office 2013 64ビットを備えたオフィスの別のマシンをチェックしたところ、UUIDもチェックさ-006E-0409-れました。どちらのマシンにも、Microsoft Office 2013(KB2850036)用のService Pack 1がインストールされています。
Gord Thompson

4
Office 2010 Pro Plus(SP2)の場合{90140000-0011-0000-0000-0000000FF1CE}、バッチスクリプトで使用する必要がありました。注{9014...ません{9114..}
AdamsTips

2
問題を解決するために公式アップデートをパッチしましたが、まだエラーが発生します。他の誰かがその問題を抱えていますか?
user218076

33

最も簡単なソリューション

ユーザーにとって、マイクロソフトからの修正リリースを12月10日まで1か月近く待つことはオプションではありません。いくつかの政府のロックされたワークステーションから問題のあるMicrosoftアップデートをアンインストールすることもありません。

回避策を適用する必要がありますが、Microsoftの提案に正確にわくわくしていません。各テーブルのクエリを作成して置き換えることです。

解決策は(SELECT * FROM Table)UPDATEコマンド内で直接テーブル名を単純なクエリに置き換えることです。これには、大量の追加のクエリ、テーブル、または関数を作成して保存する必要はありません。

例:

前:

UPDATE Table1 SET Field1 = "x" WHERE (Field2=1);  

後:

UPDATE (SELECT * FROM Table1) SET Field1 = "x" WHERE (Field2=1);  

これは、複数のデータベースやアプリケーションに実装するのがはるかに簡単です(後でロールバックする必要があります)。


20

これはWindowsの更新の問題ではなく、11月のパッチ火曜日のOfficeリリースで発生した問題です。セキュリティの脆弱性を修正するための変更により、一部の正当なクエリが破損していると報告されます。この変更はセキュリティ修正であったため、2010、2013、2016、2019、O365など、Officeのすべてのビルドに影響します。

バグはすべてのチャネルで修正されていますが、配信のタイミングは、使用しているチャネルによって異なります。

2010、2013、2016 MSI、2019ボリュームライセンスビルド、およびO365半期チャネルの場合、修正は12月10日パッチ火曜日ビルド、12月10日に予定されています。O365、月次チャネル、およびInsiderの場合、これは修正されます。 10月のフォークがリリースされたとき、現在11月24日に予定されています。

Semi-Annualチャネルの場合、バグは11328.20468で導入され、11月12日にリリースされましたが、全員に一度に公開されるわけではありません。可能であれば、12月10日まで更新を保留することをお勧めします。

この問題は、条件が指定された単一のテーブルに対する更新クエリで発生します(したがって、他のタイプのクエリは影響を受けず、テーブルのすべての行を更新するクエリも、別のクエリの結果セットを更新するクエリも影響を受けません)。そのため、ほとんどの場合、クエリを直接更新するのではなく、更新クエリを変更して、テーブルからすべてを選択する別のクエリを更新するのが最も簡単な回避策です。

つまり、次のようなクエリがあるとします。

UPDATE Table1 SET Table1.Field1 = "x" WHERE ([Table1].[Field2]=1);

次に、次のように定義された新しいクエリ(Query1)を作成します。

Select * from Table1;

元のクエリを次のように更新します。

UPDATE Query1 SET Query1.Field1 = "x" WHERE ([Query1].[Field2]=1);

公式ページ:アクセスエラー:「クエリが壊れています」


13
実際には、複数のアプリケーションに展開された数十万行のコードに行き、データの行を単純に更新するすべてのSQL更新を修正すると直言していますか?今日、そして今、新しいクエリを書いているなら、そのような回避策は可能だと思います。ただし、既存のコードとアプリケーションの場合、SQLの更新を変更するという考えは、もちろん、あらゆる問題を解決する実用的な方法ではありません。
アルバートD.カラル

5
@ AlbertD.Kallal、MVPリストから、問題の原因の説明を参照していることを知っている必要があります。問題への対処方法は実際にあなた次第であり、シナリオに何が当てはまるかはあなた次第です。ここで説明する方法は、いくつかの1つにすぎません。
Gustav

1
@ AlbertD.Kallalテーブルの名前を変更し、古いテーブル名でQueryDefsを作成しないでください。(私はそれをテストし、それが機能する場合はスクリプトを投稿します)
ComputerVersteher

プログラミングなしでそれを行うことができます。たとえば、テーブル "users"を "userst"に名前変更してクエリ名 "users"を作成します-そして、プログラミングチェーンなしで動作します...
Zvi Redler

9
@ AlbertD.Kallal:私はあなたの痛みを共有します-これがVCランタイムライブラリに影響するバグである場合、MSが修正を1か月遅らせ、「書き換え、再コンパイル、再展開」の回避策を提案することはないと思います。(公平を期すために、彼らは8月下旬にVBAの問題を迅速に修正してリリースしました。)しかし、メッセンジャーを撃たないでください-グスタフはMSの従業員ではないようです。彼らがパッチを再考してリリースすることを期待しましょう。結局のところ、たまたまAccess DBエンジンを使用する他の言語で書かれたアプリケーションにも影響します
ハインツィ

15

この問題を一時的に解決するには、使用しているAccessのバージョンによって異なります
。Access2010のアンインストール更新KB4484127
Access 2013のアンインストール更新KB4484119
Access 2016のアンインストール更新KB4484113
Access 2019必要な場合(tbc)。バージョン1808(ビルド10352.20042)からバージョン1808(ビルド10351.20054)への
ダウングレードOffice 365 ProPlusバージョン1910(ビルド12130.20344)から以前のビルドへのダウングレードについては、https: //support.microsoft.com/en-gb/help/2770432/を参照してください。 how-to-revert-to-an-earlier-version-of-office-2013-or-office-2016-clic


アンインストールしましたが、次にWindowsを起動したときに再インストールされました。再インストールを防ぐにはどうすればよいですか?
dsteele

5
@dsteele MSIバージョンでWSUSがない場合は、support.microsoft.com / en-us / help / 3073930 /… トラブルシューティングツールを使用ます。オフィスアカウント設定でCTRを無効にアップデート...オン
ComputerVersteher

5

私たちとクライアントはこの2日間でこれに苦労しており、最後にいくつかの解決策と一緒に問題を詳細に議論するためのペーパーを書きました:http : //fmsinc.com/MicrosoftAccess/Errors/query_is_corrupt/

ローカルテーブル、リンクされたAccessテーブル、さらにはリンクされたSQL Serverテーブルで更新クエリを実行すると、Accessソリューションに影響を与えるという調査結果が含まれています。

また、ADOを使用してAccessデータベースに接続するためにAccess Database Engine(ACE)を使用するMicrosoft以外のAccessソリューションにも影響します。これには、Visual Studio(WinForm)アプリ、VB6アプリ、およびAccessまたはOfficeがインストールされていないマシンのAccessデータベースを更新するWebサイトも含まれます。

このクラッシュは、PowerBI、Power Query、SSMAなどのACEを使用するMicrosoftアプリ(確認されていません)、およびもちろん、VBAを使用してAccessデータベースを変更するExcel、PowerPoint、Wordなどの他のプログラムにも影響を与える可能性があります。

問題のあるセキュリティアップデートの明らかなアンインストールに加えて、アクセス権が原因でアンインストールできない場合や、PCの制御が及ばない外部顧客にAccessアプリケーションを配布する場合のオプションも含まれています。これには、すべての更新クエリの変更とAccess 2007(小売またはランタイム)を使用したAccessアプリケーションの配布が含まれます。これは、そのバージョンがセキュリティ更新の影響を受けないためです。


4

次のモジュールを使用して、Microsoftが推奨する回避策(テーブルの代わりにクエリを使用)を自動的に実装します。念のため、まずデータベースをバックアップしてください。

使用するAddWorkaroundForCorruptedQueryIssue()回避策を追加し、RemoveWorkaroundForCorruptedQueryIssue()任意の時点でそれを削除します。

Option Compare Database
Option Explicit

Private Const WorkaroundTableSuffix As String = "_Table"

Public Sub AddWorkaroundForCorruptedQueryIssue()
    On Error Resume Next

    With CurrentDb
        Dim tableDef As tableDef
        For Each tableDef In .tableDefs
            Dim isSystemTable As Boolean
            isSystemTable = tableDef.Attributes And dbSystemObject

            If Not EndsWith(tableDef.Name, WorkaroundTableSuffix) And Not isSystemTable Then
                Dim originalTableName As String
                originalTableName = tableDef.Name

                tableDef.Name = tableDef.Name & WorkaroundTableSuffix

                Call .CreateQueryDef(originalTableName, "select * from [" & tableDef.Name & "]")

                Debug.Print "OldTableName/NewQueryName" & vbTab & "[" & originalTableName & "]" & vbTab & _
                            "NewTableName" & vbTab & "[" & tableDef.Name & "]"
            End If
        Next
    End With
End Sub

Public Sub RemoveWorkaroundForCorruptedQueryIssue()
    On Error Resume Next

    With CurrentDb
        Dim tableDef As tableDef
        For Each tableDef In .tableDefs
            Dim isSystemTable As Boolean
            isSystemTable = tableDef.Attributes And dbSystemObject

            If EndsWith(tableDef.Name, WorkaroundTableSuffix) And Not isSystemTable Then
                Dim originalTableName As String
                originalTableName = Left(tableDef.Name, Len(tableDef.Name) - Len(WorkaroundTableSuffix))

                Dim workaroundTableName As String
                workaroundTableName = tableDef.Name

                Call .QueryDefs.Delete(originalTableName)
                tableDef.Name = originalTableName

                Debug.Print "OldTableName" & vbTab & "[" & workaroundTableName & "]" & vbTab & _
                            "NewTableName" & vbTab & "[" & tableDef.Name & "]" & vbTab & "(Query deleted)"
            End If
        Next
    End With
End Sub

'From https://excelrevisited.blogspot.com/2012/06/endswith.html
Private Function EndsWith(str As String, ending As String) As Boolean
     Dim endingLen As Integer
     endingLen = Len(ending)
     EndsWith = (Right(Trim(UCase(str)), endingLen) = UCase(ending))
End Function

GitHubリポジトリで最新のコードを見つけることができます

AddWorkaroundForCorruptedQueryIssue()_Tableシステム以外のすべてのテーブルにサフィックスを追加IceCreamsIceCreams_Tableます。たとえば、テーブルの名前はに変更されます。

また、元のテーブル名を使用して新しいクエリを作成し、名前を変更したテーブルのすべての列を選択します。この例では、クエリに名前が付けられIceCreams、SQLが実行されますselect * from [IceCreams_Table]

RemoveWorkaroundForCorruptedQueryIssue() 逆のアクションを行います。

外部の非MDBテーブル(SQL Serverなど)を含め、あらゆる種類のテーブルでこれをテストしました。ただし、特定の場合、特にテーブルを使用した元のクエリの品質が低いか非常に複雑な場合、テーブルの代わりにクエリを使用すると、最適化されていないクエリがバックエンドデータベースに対して実行される可能性があることに注意してください。

(そしてもちろん、コーディングスタイルによっては、アプリケーションで問題が発生する可能性もあります。そのため、修正が一般的に機能することを確認した後、すべてのオブジェクトをテキストとしてエクスポートして検索置換を使用することは決して悪い考えではありませんテーブル名の出現がクエリではなくテーブルに対して実行されることを保証する魔法。)

私の場合、この修正はほとんど副作用なしで機能します。以前に作成したときにシステムテーブルとしてマークしていなかったUSysRibbons_TableためUSysRibbons、手動でに名前を変更する必要がありました。


私はあなたがシステムテーブルを決定してTableDef.Attributesそれを私の答えにコピーするのが好きです;)元に戻す機能は良い考えです(ただし、名前の変更前に接尾辞のあるテーブルがないため、古い名前と新しい名前をテーブルに保存する必要があります)。他のいくつかの部分に欠陥があります(たとえば、テーブルがサフィックスで終了するか、新しい名前がすでに使用されているか、On Error Resume Next後でエラーを処理せずに)RubberduckVBAを知っていますか?このアドインは、コードを検査し、他のすべての機能に加えて、improventmに対する素晴らしい提案を行います。
ComputerVersteher

そして、私たちのアプローチが引き起こす可能性のあるバグを指摘する必要があります(私の回答に関する@Ericsコメントを参照)
ComputerVersteher

ああ、同じような答えがすでにここにあるとは思わなかったので、レビューをありがとう!サフィックスは独自の定数で定義されているため、サフィックスをすでに使用している既存のオブジェクトがすでに定義されている場合は、簡単に変更できます。それ以外の場合、スクリプトはそのまま機能しますが、だれでも個々のニーズに合わせてスクリプトを変更することをお勧めします。このスクリプトは、さまざまな外部データベースソースへの外部/リンクテーブルを含むかなり大きなプロジェクト(400以上のテーブル)でテストされています。私は、Rubberduckについては知りませんでした(MZ-Toolsについてのみ)。ぜひチェックしてみます!
lauxjpn

3

PowerShellを使用してこのプロセスを自動化する方法を探している人のために、役立つと思われるリンクをいくつか紹介します。

問題のある更新を検出して削除する

こちらのhttps://www.arcath.net/2017/09/office-update-removerで利用可能なPowerShellスクリプトがあり、特定のOffice更新(KB番号として渡される)をレジストリで検索し、次の呼び出しを使用して削除します。msiexec.exe。このスクリプトは、レジストリキーから両方のGUIDを解析して、適切な更新を削除するコマンドを作成します。

私が提案する1つの変更は、KB4011626およびその他のOffice更新プログラムをアンインストール/REBOOT=REALLYSUPPRESSする方法(追加の参照:https : //docs.microsoft.com/en-us/windows/win32/msi/uninstalling-patches)で説明されているように使用することです。作成しているコマンドラインは次のようになります。

msiexec /i {90160000-0011-0000-0000-0000000FF1CE} MSIPATCHREMOVE={9894BF35-19C1-4C89-A683-D40E94D08C77} /qn REBOOT=REALLYSUPPRESS

スクリプトを実行するコマンドは次のようになります。

OfficeUpdateRemover.ps1 -kb 4484127

更新がインストールされないようにする

ここで推奨されるアプローチは、更新を非表示にしいるようです。明らかにこれは手動で行うことができますが、自動化に役立つPowerShellスクリプトがいくつかあります。このリンク:https : //www.maketecheasier.com/hide-updates-in-windows-10/はプロセスを詳細に説明していますが、ここで要約します。

  1. Windows Update PowerShell Moduleをインストールします
  2. 次のコマンドを使用して、KB番号で更新を非表示にします。

    Hide-WUUpdate -KBArticleID KB4484127

うまくいけば、これは他の誰かの助けになるでしょう。


3

MS-回避策用のVBAスクリプト:

少なくともMSIバージョンについては、可能であれば(私のコードを試さない限り)バグのあるアップデートを削除することをお勧めします。回答https://stackoverflow.com/a/58833831/9439330を参照してください

CTR(Click-To-Run)バージョンの場合は、Officeの11月の更新をすべて削除する必要があります。これにより、重大なセキュリティ問題が発生する可能性があります(重要な修正が削除されるかどうかは不明です)。

@Ericのコメントから:

  • を使用Table.Tablenameしてフォームをバインドすると、以前のtable-nameがquery-name!になるため、フォームがバインド解除されます。
  • OpenRecordSet(FormerTableNowAQuery, dbOpenTable) 失敗します(クエリではなく、テーブルではなくなります)

注意!Office 2013 x86 CTRのNorthwind.accdbに対して簡単にテストされただけで、保証はありません。

Private Sub RenameTablesAndCreateQueryDefs()
With CurrentDb
    Dim tdf As DAO.TableDef
    For Each tdf In .TableDefs

        Dim oldName As String
        oldName = tdf.Name

        If Not (tdf.Attributes And dbSystemObject) Then 'credit to @lauxjpn for better check for system-tables
            Dim AllFields As String
            AllFields = vbNullString

            Dim fld As DAO.Field

            For Each fld In tdf.Fields
                AllFields = AllFields & "[" & fld.Name & "], "
            Next fld

            AllFields = Left(AllFields, Len(AllFields) - 2)
            Dim newName As String
            newName = oldName

            On Error Resume Next
            Do
                Err.Clear
                newName = newName & "_"
                tdf.Name = newName
            Loop While Err.Number = 3012
            On Error GoTo 0

            Dim qdf As DAO.QueryDef

            Set qdf = .CreateQueryDef(oldName)
            qdf.SQL = "SELECT " & AllFields & " FROM [" & newName & "]"
        End If
    Next
    .TableDefs.Refresh

End With
End Sub

テスト用:

Private Sub TestError()
With CurrentDb
    .Execute "Update customers Set City = 'a' Where 1=1", dbFailOnError 'works

    .Execute "Update customers_ Set City = 'b' Where 1=1", dbFailOnError 'fails
End With
End Sub

4
この回避策は、テーブルにバインドされたサブフォーム(クエリに再バインドする必要があります)およびハードコードされたテーブル名を持つtabledefを使用するコードを台無しにすることに注意してください。注意して使用してください。これは、アプリケーションが何をしているかに応じて、1つのバグを修正するだけで2つの新しいバグを作成する可能性があります。
エリックA

@ErikAもちろん回避策だけですが、問題なくフォームInventory to reorder Subform for HomeInventoryテーブルをバインドできHomeます。フォームをテーブルではなくクエリにバインドすることをお勧めしませんか(テーブルのようにバインドしていませんSelect * From tableか?)。
ComputerVersteher

2
サブフォームをテーブルにバインドする場合、通常はTable.TableName表記法を使用して行います。その場合はSELECT * FROM TableName代わりに、あなたはもちろんの罰金のです。ただし、を使用するTable.TableName場合、テーブルの名前を変更すると、サブフォームはバインドされなくなります。
エリックA

@エリカ:それは本当です。それを行うことによるメリットは?
ComputerVersteher

3
私の知る限りではありませんが、より簡潔です。にもかなりの利点がTableDefs!MyTableName.OpenRecordset(dbOpenTable)ありますが(インデックスシークのサポート)、これも使用する傾向があり、アプローチでエラーが発生します
Erik A

2

currentDb.ExecuteDocmd.RunSQLをヘルパー関数に置き換えました。いずれかの更新ステートメントにテーブルが1つしか含まれていない場合、SQLステートメントを前処理して変更できます。dual(単一行、単一列)テーブルが既にあるので、fakeTableオプションを使用しました。

:これによってクエリオブジェクトが変更されることはありません。VBAを介したSQL実行のみを支援します。If you would like to change your query objects, use FnQueryReplaceSingleTableUpdateStatements and update your sql in each of your querydefs. Shouldn't be a problem either.

これは単なる概念(If it's a single table update modify the sql before execution)です。必要に応じて調整してください。この方法では、各テーブルの置換クエリは作成されません(これは最も簡単な方法ですが、独自の欠点があります。つまり、パフォーマンスの問題)。

+ポイント: MSがバグを修正しても何も変更されない場合でも、このヘルパーを引き続き使用 できます。将来、別の問題が発生した場合でも、pre-processSQLを1か所で準備できます。更新方法をアンインストールすることはしませんでした。これは、管理者アクセスが必要であり、すべてのユーザーが正しいバージョンになるまでに時間がかかりすぎるためです+アンインストールしても、一部のエンドユーザーのグループポリシーによって最新の更新が再度インストールされます。同じ問題に戻ります。

ソースコードにアクセスできuse this method、問題のあるエンドユーザーがいないことを100%確信している場合。

Public Function Execute(Query As String, Optional Options As Variant)
    'Direct replacement for currentDb.Execute

    If IsBlank(Query) Then Exit Function

    'invalid db options remove
    If Not IsMissing(Options) Then
        If (Options = True) Then
            'DoCmd RunSql query,True ' True should fail so transactions can be reverted
            'We are only doing this so DoCmd.RunSQL query, true can be directly replaced by helper.Execute query, true.
            Options = dbFailOnError
        End If
    End If

    'Preprocessing the sql command to remove single table updates
    Query = FnQueryReplaceSingleTableUpdateStatements(Query)

    'Execute the command
    If ((Not IsMissing(Options)) And (CLng(Options) > 0)) Then
        currentDb.Execute Query, Options
    Else
        currentDb.Execute Query
    End If

End Function

Public Function FnQueryReplaceSingleTableUpdateStatements(Query As String) As String
    ' ON November 2019 Microsoft released a buggy security update that affected single table updates.
    '/programming/58832269/getting-error-3340-query-is-corrupt-while-executing-queries-docmd-runsql

    Dim singleTableUpdate   As String
    Dim tableName           As String

    Const updateWord        As String = "update"
    Const setWord           As String = "set"

    If IsBlank(Query) Then Exit Function

    'Find the update statement between UPDATE ... SET
    singleTableUpdate = FnQueryContainsSingleTableUpdate(Query)

    'do we have any match? if any match found, that needs to be preprocessed
    If Not (IsBlank(singleTableUpdate)) Then

        'Remove UPDATe keyword
        If (VBA.Left(singleTableUpdate, Len(updateWord)) = updateWord) Then
            tableName = VBA.Right(singleTableUpdate, Len(singleTableUpdate) - Len(updateWord))
        End If

        'Remove SET keyword
        If (VBA.Right(tableName, Len(setWord)) = setWord) Then
            tableName = VBA.Left(tableName, Len(tableName) - Len(setWord))
        End If

        'Decide which method you want to go for. SingleRow table or Select?
        'I'm going with a fake/dual table.
        'If you are going with update (select * from T) as T, make sure table aliases are correctly assigned.
        tableName = gDll.sFormat("UPDATE {0},{1} SET ", tableName, ModTableNames.FakeTableName)

        'replace the query with the new statement
        Query = vba.Replace(Query, singleTableUpdate, tableName, compare:=vbDatabaseCompare, Count:=1)

    End If

    FnQueryReplaceSingleTableUpdateStatements = Query

End Function

Public Function FnQueryContainsSingleTableUpdate(Query As String) As String
    'Returns the update ... SET statment if it contains only one table.

    FnQueryContainsSingleTableUpdate = ""
    If IsBlank(Query) Then Exit Function

    Dim pattern     As String
    Dim firstMatch  As String

    'Get the pattern from your settings repository or hardcode it.
    pattern = "(update)+(\w|\s(?!join))*set"

    FnQueryContainsSingleTableUpdate = FN_REGEX_GET_FIRST_MATCH(Query, pattern, isGlobal:=True, isMultiline:=True, doIgnoreCase:=True)

End Function

Public Function FN_REGEX_GET_FIRST_MATCH(iText As String, iPattern As String, Optional isGlobal As Boolean = True, Optional isMultiline As Boolean = True, Optional doIgnoreCase As Boolean = True) As String
'Returns first match or ""

    If IsBlank(iText) Then Exit Function
    If IsBlank(iPattern) Then Exit Function

    Dim objRegex    As Object
    Dim allMatches  As Variant
    Dim I           As Long

    FN_REGEX_GET_FIRST_MATCH = ""

   On Error GoTo FN_REGEX_GET_FIRST_MATCH_Error

    Set objRegex = CreateObject("vbscript.regexp")
    With objRegex
        .Multiline = isMultiline
        .Global = isGlobal
        .IgnoreCase = doIgnoreCase
        .pattern = iPattern

        If .test(iText) Then
            Set allMatches = .Execute(iText)
            If allMatches.Count > 0 Then
                FN_REGEX_GET_FIRST_MATCH = allMatches.item(0)
            End If
        End If
    End With

    Set objRegex = Nothing

   On Error GoTo 0
   Exit Function

FN_REGEX_GET_FIRST_MATCH_Error:
    FN_REGEX_GET_FIRST_MATCH = ""

End Function

今ちょうどCTRL+F

検索と置換するdocmd.RunSQLhelper.Execute

検索と置換する[currentdb|dbengine|or your dbobject].executehelper.execute

楽しんで!


0

このバグも修正されましたが、エンドユーザーが更新できない可能性のあるさまざまな企業(雇用主のように...)にはまだ修正が反映されていません。

これがの回避策ですDoCmd.RunSQL "UPDATE users SET uname= 'bob' WHERE usercode=1"。問題のクエリをコメントアウトして、以下のコードをドロップしてください。

    'DoCmd.RunSQL "UPDATE users SET uname= 'bob' WHERE usercode=1"
    Dim rst As DAO.Recordset
    Set rst = CurrentDb.OpenRecordset("users")
    rst.MoveLast
    rst.MoveFirst
    rst.FindFirst "[usercode] = 1" 'note: if field is text, use "[usercode] = '1'"
    rst.Edit
    rst![uname] = "bob"
    rst.Update
    rst.Close
    Set rst = Nothing

きれいだとは言えませんが、それで仕事は終わりです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.