2016-04-04 16 views
1

アクセスプログラムのモジュールをコーディングする際に問題が発生しているので、私はあなたに手を差し伸べています。アクセスのためのvbaの再帰関数を持つ "スタックの空き領域"

はじめに:製品、Receipes、Ordonnancement &コマンド:

私は4つのテーブルを得ました。 調和とコマンドは同じ構造を持ち、2つ目はレシピを通るコマンドの処理の結果です。 VBAモジュールの

目標:

私はreceipesを通じてコマンドを処理することによって、Ordonnancementテーブルにレコードを作成するために、モジュールを作成しています。具体的には、私はレシピテーブルをループし、すべての製品で1つの日付の必要性を生成することができるレシピの可変深度に対処するために再帰関数を使用します。

備考:

-Iは、通常のデータベースで動作するようにEFを使用してC#で働いています。 Accessのレコードセットの可能性を直接使用するいくつかの試みの後、私はReceipeLignとOrdoLignのPOCOクラスを生成し、これらのオブジェクトのコレクション内のテーブルのデータを保管し、それらのオブジェクトで作業し、Accessテーブルにレコードを追加しますRecordSet。

- 私はフランス語で作業しています。だから、私はいくつか翻訳してみんなが理解できるようにしました。完璧ではないかもしれませんが、私には分かりません。

コード:

Option Compare Database 
Option Explicit 

Dim cnc As New ADODB.Connection 
Dim CRecordSet As New ADODB.Recordset 
Dim FTRecordSet As New ADODB.Recordset 
Dim ORecordSet As New ADODB.Recordset 

Public Sub GenerateOrdonnancement() 

'Retrieving info from tables Commandes & FT in RecordSets. 
Set cnc = CurrentProject.Connection 
Set CRecordSet = cnc.Execute("SELECT * FROM Commandes") 
Set FTRecordSet = cnc.Execute("SELECT * FROM FichesTechniques") 
Set ORecordSet = cnc.Execute("SELECT * FROM Ordonnancement") 

'Creation of the list to receive data from the tables 
Dim Commandes As New Collection 
Dim FicheTechniques As New Collection 

'Retrieving commands and receipes 
Dim Commande As ligneOrdo 
Dim ordo As ligneOrdo 
Dim FT As ligneFT 

Do Until CRecordSet.EOF 

    Set Commande = New ligneOrdo 
    Commande.DateCommande = CRecordSet("dateCommande").Value 
    Commande.Produit = CRecordSet("Produit").Value 
    Commande.Quantite = CRecordSet("quantite").Value 
    Commandes.Add Commande 
    CRecordSet.MoveNext 

Loop 
CRecordSet.Close 


Do Until FTRecordSet.EOF 

    Set FT = New ligneFT 
    FT.Nom = FTRecordSet("Nom").Value 
    FT.Ingredient = FTRecordSet("Ingredient").Value 
    FT.Quantite = FTRecordSet("quantité").Value 
    FT.IsComposed = FTRecordSet("Composé").Value 
    FicheTechniques.Add FT 
    FTRecordSet.MoveNext 

Loop 
FTRecordSet.Close 


'creation of the collection of ordo 
'Later: versionning of the Ordonnancements 
Dim AProduire As New Collection 

Dim mr As ligneOrdo 
For Each mr In Commandes 
    Dim coll As Collection 
    Set coll = CreateOrdoLigne(mr, FicheTechniques) 
    Dim item As New ligneOrdo 
    For Each item In coll 
     AProduire.Add item 
    Next item 
Next mr 

'Adding and saving the coll AProduire in the RecordSetO 
cnc.BeginTrans 
Dim item2 As ligneOrdo 
For Each item2 In AProduire 
    ORecordSet.AddNew 
    ORecordSet("DateCommande").Value = item2.DateCommande 
    ORecordSet("Produit").Value = item2.Produit 
    ORecordSet("Quantite").Value = item2.Quantite 
    ORecordSet.Update 
Next item2 

ORecordSet.Close 

cnc.CommitTrans 

End Sub 

Function CreateOrdoLigne(ligne As ligneOrdo, FT As Collection) As Collection 

Dim ordo As New Collection 

Dim ligneFT As Variant 
'Loop through the receipes 
For Each ligneFT In FT 
    If ligneFT.Nom = ligne.Produit Then 
     Dim AProduire As New ligneOrdo 
     AProduire.Produit = ligneFT.Ingredient 
     AProduire.DateCommande = ligne.DateCommande 
     AProduire.Quantite = ligne.Quantite * ligneFT.Quantite 
     ordo.Add AProduire 
     If ligneFT.IsComposed = True Then 
      Dim ordoList2 As New Collection 
      Set ordoList2 = CreateOrdoLigne(AProduire, FT) 
      Dim recordOrdo As ligneOrdo 
      For Each recordOrdo In ordoList2 
       ordo.Add recordOrdo 
      Next recordOrdo 
      Set ordoList2 = Nothing 
     End If 
     Set AProduire = Nothing 
    End If 
Next ligneFT 


Set CreateOrdoLigne = ordo 

End Function 

問題文: "スタック領域不足"、いくつかの研究内容A後のようだ:モジュールを実行

、私は、ファイル名を指定して実行時エラー28を取得しますそのような厳しい環境で再帰関数を扱う一般的なこと。問題は、私は本当にプロセスを最適化することはできません。私はこのエラーやアイデアを回避するための直接的な方法を探しています。別の方法でこの問題に取り組んでいます。

はあなたのすべてをありがとう、

+0

通常、非終端再帰関数の症状です。無限のコールループを作成していませんか?例: 'Debug.Print ligne.Produit'を関数の先頭に追加します。 Ctrl + gを押すとイミディエイトウィンドウが開き、出力が得られます。 – Andre

+0

エラーが発生しているラインはどれですか? – Absinthe

+0

関数CreateOrdoLigneを見てください....あなたはその関数をその内部から呼び出しています。つまり、通常は良いアイデアではない、Set ordoList2 = CreateOrdoLigne(AProduire、FT)を設定してください... –

答えて

1

だから@Andreの助けを借りて、いくつかのデバッグの後、私はサイズに、したがって、エラー、再帰性は無限だったことが分かりました。 それでも、Accessはあまりにも多くのデータを生成することができず、その変更をデータベースにコミットすることができます。

私はで構成されている問題、回避する方法を発見した:

  • コレクションにストックされる機能を使用して回避することができます。私はそのために関数をサブ関数に変換しました。
  • 生成プロセスに沿ってデータベースへの変更をコミットします。
  • obj =繰り返し可能なプロセスでもう必要がない場合は何も表示されません。

私が学んだと、おそらく他の人

  • はそれが無限作ることができるものを見るために、再帰的プロセスを分析するのに役立つ可能性がどのような、
  • 応じてエラーハンドラを定義します。Debug.Printがでデバッグするための効率的な方法でありますvba ACCESS:データを生成し、プロセス全体をチェックします。

ありがとうございます@Andreさんとあなたの時間の他の人は、他の人に役立つことを願っています。

関連する問題