2009-04-08 15 views
3

ドキュメントテンプレートのWord/VBAマクロを作成しています。ユーザーがテンプレートから新しい文書を保存/作成するたびに、文書にはテキストに埋め込まれたIDが必要です。このIDの自動インクリメントはどのように実装できますか(できるだけシンプルに) IDは数値です。Wordマクロで自動インクリメントを実装する

システムには、同じIDを取得する異なる文書を回避するための何らかのメカニズムが必要ですが、負荷は非常に低くなります。約20人がこのテンプレート(イントラネット上)を使用し、1週間に20の新しい文書を作成します。

私は、マクロからロックしたりロックを解除したり、SQLiteデータベースでPHPページを呼び出すというテキストファイルを持っていると思っていましたが、他にもスマートなソリューションはありますか?

UUIDやGUIDは人間と機械の両方で使用できる必要があるため、使用できないことに注意してください。私たちの顧客は、電話で言うことができなければなりません: "...そしてこれについては、ID 436で...?"

+0

本当に必要なのは、すべての保存とすべてのユーザーに固有のIDです。 – jpinto3912

+0

いいえ、すべてのドキュメントの一意のIDです。 –

+0

おそらく、「ユーザーが新しい文書を保存するたびに...」という言い回しをする必要があるかもしれません。これは、実際には保存カウントプロセスが進行中であることを暗示しているからです(これはわかりません) – jpinto3912

答えて

0

私が何の並行性の問題がないことを意味し、独占的な権利を持つテキストファイルを開いて更新する方法を見つけたようだ:それは返さないまで

Private Function GetNextID(sFile As String) As Integer 
    Dim nFile As Integer 

    nFile = FreeFile 

    On Error Resume Next 
    Open sFile For Binary Access Read Write Lock Read Write As #nFile 
    If Err.Number <> 0 Then 
     ' Return -1 if the file couldn't be opened exclusively 
     GetNextID = -1 
     Err.Clear 
     Exit Function 
    End If 
    On Error GoTo 0 

    GetNextID = 1 + Val(Input(LOF(nFile), #nFile)) 
    Put #nFile, 1, CStr(GetNextID) 
    Close #nFile 
End Function 

は、単純にこの関数を呼び出す-1もうきちんとした

1

あなたは次のID番号をどこかに保存する必要があります。テキストファイルの考え方はどれも良いものです。何らかの理由でロックされているかアクセスできない可能性があるだけです。

1つの番号のデータベースを使用することは過剰です。私の頭の上オフ

1

:オートメーションを使用して、外部DBなど

  • Excelを使用。 を検索してください(Litexが気に入っています)。
+0

私たちを通して骨ここに!どちらかについて精巧にすると、私たちは皆それから学びます。 – jpinto3912

2

これはWordとExcel(または私が想定しているAccess)を使ってVBAで完全に処理することができますが、Accessを使用するのは自然ではありません。

まず、新しいExcelワークブックを作成し、ワードドキュメント(私はC:\ Desktop \ Book1.xls)にアクセスできる場所に保存します。セルA1に数値を入力して値をシードすることもできます。 Word文書で

、あなたのDocument_Open()サブルーチンにこれを入力します。

Private Sub Document_Open() 

Dim xlApp  As Excel.Application 
Dim xlWorkbook As Excel.Workbook 
Dim xlRange  As Excel.Range 
Dim sFile  As String 
Dim LastID  As Integer 
Dim NewID  As Integer 

'Set to the location of the Excel "database" 
sFile = "C:\Desktop\Book1.xls" 

'Set all the variables for the necessary XL objects 
Set xlApp = New Excel.Application 
Set xlWorkbook = xlApp.Workbooks.Open(sFile) 

'The used range assumes just one column in the first worksheet 
Set xlRange = xlWorkbook.Worksheets(1).UsedRange 

'Use a built-in Excel function to get the max ID from the used range 
LastID = xlApp.WorksheetFunction.Max(xlRange) 

'You may want to come up with some crazy algorithm for 
'this, but I opted for the intense + 1 
NewID = LastID + 1 

'This will prevent the save dialog from prompting the user 
xlApp.DisplayAlerts = False 

'Add your ID somewhere in the document 
ThisDocument.Range.InsertAfter (NewID) 

'Add the new value to the Excel "database" 
xlRange.Cells(xlRange.Count + 1, 1).Value = NewID 

'Save and close 
Call xlWorkbook.Save 
Call xlWorkbook.Close 

'Clean Up 
xlApp.DisplayAlerts = True 
Call xlApp.Quit 
Set xlWorkbook = Nothing 
Set xlApp = Nothing 
Set xlRange = Nothing 

End Sub 

を私はすべての手段を再要因によってそれ心ゆくまで、これは背の高い手順で実現します。これはちょっとした試練だった。また、VBAの参照によってExcelオブジェクトライブラリへの参照を追加する必要があります。あなたはそれがどのように動作するかについてご質問がある場合はお知らせください。

希望に役立ちます!

+0

これは、異なるユーザーからの同時保存を解決しないと思います。あなたはより良くすることができます。 – jpinto3912

+0

質問に記載されているとおり、20人のユーザーが週に約20回節約します。並行性は大きな問題ではありません。 Excelファイルは、おそらく共有する必要はありません。それが開いている場合はエラーを投げて、もう一度やり直してください。この手法は、拡張性はありませんが、要件を満たす必要があります。 – guillermooo

0

"マクロからロックしてロックを解除するテキストファイル"が最も安全な方法です。 DOCIDファイルには、最後にACTUALLYで使用されたIDの1つの番号しかありません。

A)ファイルを読み込み(書き込み/追加モードではない)、文書DOC_ID = FILE_ID + 1の変数に保存して文書を保存します。一時的にDOCIDファイルを終了し、DOC_IDを読み書きするためにオープン/作成します。ファイルを閉じます。すべてがうまくいけば、閉じる、あなたは安全です、そうでなければ、Aに戻ります)。

あなたが考慮したいと思うかもしれません:なしファイルは、この文書ID 100とそれを作成見つからない場合、Aにおけるながら無UPSの災害からの回復の尺度として)

私がいるかどうかを確認するにはあまりにも疲れています同時実行シナリオでデッドロックが発生する可能性があります。

価値があると思えば、ここにコードを入れることができます。

+0

申し訳ありませんが、IDは増分IDでなければなりません。IDは改訂/保存ではなく文書を識別します。また、IDは上記のように人間に優しいものでなければならない。 –

3

もう少し考えてみてください。もう1つ考えてみてください。以前のIDのカタログに興味がない場合は、カスタムドキュメントプロパティを使用して、最後に使用されたIDを格納することができます。

Word 97-2003では、「ファイル/プロパティ」に移動してカスタムタブを選択し、そこに名前と値を割り当てることで、カスタムプロパティを追加できます。 Word 2007のカスタムドキュメントプロパティを追加することは少しばかり埋もれてしまい、私の頭の上から外して、私はそれが "Office Button/Prepare/Document Properties"だと思うし、拡張プロパティ用の小さなドロップダウンボックスを選択すると、 2007年前の対話

以下の例では、私は単に「DocumentID」という名前を付けて、それにゼロの初期値を割り当てました。

カスタムドキュメントプロパティを更新するためのコードの該当ビットがある:概念実証として

ThisDocument.CustomDocumentProperties("DocumentID").Value = NewValue 

、私はの.dotファイルを作成し、Document_New()イベントに次のコードを使用:

Sub UpdateTemplate() 

    Dim Template As Word.Document 
    Dim NewDoc  As Word.Document 
    Dim DocumentID As DocumentProperty 
    Dim LastID  As Integer 
    Dim NewID  As Integer 

    'Get a reference to the newly created document 
    Set NewDoc = ActiveDocument 

    'Open the template file 
    Set Template = Application.Documents.Open("C:\Doc1.dot") 

    'Get the custom document property 
    Set DocumentID = Template.CustomDocumentProperties("DocumentID") 

    'Get the current ID 
    LastID = DocumentID.Value 

    'Use any method you need for determining a new value 
    NewID = LastID + 1 

    'Update and close the template 
    Application.DisplayAlerts = wdAlertsNone 
    DocumentID.Value = NewID 
    Template.Saved = False 
    Template.Save 
    Template.Close 

    'Remove references to the template 
    NewDoc.AttachedTemplate = NormalTemplate 

    'Add your ID to the document somewhere 
    NewDoc.Range.InsertAfter ("The documentID for this document is " & NewID) 
    NewDoc.CustomDocumentProperties("DocumentID").Value = NewID 

End Sub 

幸運を祈る!

+0

これはとても巧妙ですが、残念ながら元のテンプレートを編集すると他の問題が発生しました。 –

+0

私のためにうまくいった、ありがとう!私はあなたがなぜこれらの行が必要なのか、それが何であるのか不思議です: 'Application.DisplayAlerts = wdAlertsNone'; 'Template.Saved = False';また、なぜテンプレートへの参照を削除する必要がありますか? –

+0

誰でも知っていますか?テンプレートファイルを開く行を作る方法はありますか?( 'Set Template = Application.Documents.Open(" C:\ Doc1.dot ")')は相対パスを使います。または、ドキュメントを作成するために使用されるテンプレートファイルへのパスを取得する別の方法がありますか?ユーザーがコードを壊さずにファイルを移動できるようにしたい。 –