Microsoft Access 掲示板

views
4 フォロー
6,283 件中 1,521 から 1,560 までを表示しています。
16
nokonoko 2023/07/21 (金) 11:07:09 3e2e6@54883

失礼しました
Cesllになってました。
直したら、動きました。

こんなくだらないことに、たくさん回答いただき、大変申し訳ないです。
Hiroton様もありがとうございました。

ほかに問題がないか後で検証します。

15
nokonoko 2023/07/21 (金) 11:04:14 3e2e6@54883

ありがとうございます。

コメントアウトなどの処置をして、検証しました。

xls.Range(xls.cesll(21 + intNumRow, 1), xls.cells(21 + intNumRow + intGNumRow, 1)).entirerow.Insert

のところで、「実行時エラー‘438‘: オブジェクトは、このプロパティまたはメソッドをサポートしていません。」が出ます。

その前までは、望んでいるような結果が出ています。

14
hatena 2023/07/21 (金) 10:55:59 修正

ざっと見た感じではコード自体に問題はなさそうです。
(もっとスマートな書き方かあるかもということは置いておいて)

とりあえずうまくいかないとき、原因を特定するためのデバッグ作業をしてみましょう。
まず、
On Error GoTo Err_Handler
はコメントアウトしておきましょう。これがあるとどこでエラーがある分かりません。
次に、

Set xls = CreateObject("Excel.Application")
xls.Visible = True '挿入
With xls
    '画面の再描画を抑止
'    .screenUpdating = False コメントアウト


としてエクセルを表示させ、画面の再描画停止をやめましょう。
これでエクセル上での操作を目で確認できます。

そのうえで1行ずつステップ実行して動作を確認しつつ、どこでどのようなエラーが出るのか確認しましょう。ステップ実行 は下記リンクを参考にしてください。

デバッグの基本 – ステップ実行 | ExcelVBA入門 自宅でプログラミング

このデバッグ作業をして、どの行でどのようなエラーがでるのか教えてください。

13
nokonoko 2023/07/21 (金) 10:43:23 3e2e6@54883 >> 12

失礼いたしました。
もともとのコードがぐちゃぐちゃで、そのまま貼り付けるにははばかられるようなものだったので、
修正をして貼り付けたときに、ミスが出たのだと思います。

12
hiroton 2023/07/21 (金) 10:33:38 22c35@f966d

書き込みがある度、コードが変わりますね
落ち着いて、コピペをしてください

            xls.Range(xls.cesll(21 + intNumRow, 1), xls.cells(21 + intNumRow + intGNumRoW, 2)).entirerow .Insert

            xls.Range(xls.cesll(21 + intNumRow, 1), xls.cells(21 + intNumRow + intGNumRoW, 2)).entirerow .Insert

11
nokonoko 2023/07/21 (金) 10:11:52 3e2e6@54883

明らかに不要なところを除きました。
実行時に同様のエラーが出ます。

Private Sub cmd練習_Click()
   
On Error GoTo Err_Handler

Dim i As Integer
Dim xls As Object
Dim intNumRow, intGNumRoW As Integer 
Dim strTemplateDir, strTemplateBook As String

intNumRow = 3
intGNumRoW = 5

'テンプレートの保存先フォルダ
    strTemplateDir = Application.CurrentProject.Path & "\データ\テンプレート\"
'テンプレートのファイル名
    strTemplateBook = "原紙.xlsx"
    
'Excelオブジェクトを生成
Set xls = CreateObject("Excel.application")
With xls
    '画面の再描画を抑止
    .screenUpdating = False
    'テンプレートファイルを開く
    .Workbooks.Open strTemplateDir & strTemplateBook
    'ワークシートをコピー
    .Workbooks(strTemplateBook).worksheets("xxx").Copy
    'テンプレートファイルを閉じる
    .Workbooks(strTemplateBook).Close

    'ワークシートに行追加 A
    If intNumRow > 1 Then
        For i = 1 To intNumRow - 1
            .Range("A16").entirerow.Insert
        Next
    End If
 
    'ワークシートに行追加 B
        If intGNumRoW > 1 Then
            xls.Range(xls.cesll(21 + intNumRow, 1), xls.cells(21 + intNumRow + intGNumRoW, 2)).entirerow .Insert
        End If
    
    '画面の再描画を元に戻す
    .screenUpdating = True
End With

MsgBox "保存されました。"
DoCmd.Close acForm, Me.Name

    'Excelを終了
xls.Quit
Set xls = Nothing

Exit_here:
If xls Is Nothing Then Exit Sub
Exit Sub

Err_Handler:
MsgBox Err.Number & vbTab & Err.Description, vbExclamation
Resume Exit_here

End Sub
10
nokonoko 2023/07/21 (金) 09:31:09 3e2e6@54883

ご指摘ありがとうございます。

そのままでは3000字を越えてしまうので、少し検討します。

9

まず、回答の前に、一言。
コードの一部の抜粋を提示するより、可能ならば Sub から End Sub まですべて提示した方が話がはやいでしょう。
もし、コードが提示するには長すぎるなら、処理を複数のサブルーチンに分割することを検討した方がいいでしょう。
今回も、結局リンク先のコードをみて類推して回答することになりますが、認識違いで無駄なやりとりになる可能性もあります。


こちらで、リンク先のコードと提示のコードからサンプルを作成して実験したところ、下記を修正したら正常に動作しました。

With xls
    .screenUpdating = False
    .workbooks.Open strTemplateDir & strTemplateBook
    .workbooks(strTemplateBook).Worksheets("xxx").Copy
    .workbooks(strTemplateBook).Close
-  .Range(xls.cells(21+i , 1), xls.cells(21+i+j , 1).entirerow.Insert
+  .Range(xls.cells(21+i , 1), xls.cells(21+i+j , 1)).entirerow.Insert

ようは不足していた)を追加しただけです。

ただし、この修正前のコードでは構文エラーになり実行すらできませんので、

「オブジェクトは、このプロパティまたはメソッドをサポートしていません」

というようなエラーにはなりませんので、提示されていない他の部分に原因があるでしょう。

ということで、やはりコード全体を提示してください。

8
nokonoko 2023/07/21 (金) 08:17:38 修正 3e2e6@54883

お二方回答ありがとうございます。
回答を見たばかりなので、内容確認できてはおりません。

中略した部分も提示してください。

Set xls = CreateObject("Excel.application")
With xls
    .screenUpdating = False
    .workbooks.Open strTemplateDir & strTemplateBook
    .workbooks(strTemplateBook).Worksheets("xxx").Copy
    .workbooks(strTemplateBook).Close
  .Range(xls.cells(21+i , 1), xls.cells(21+i+j , 1).entirerow.Insert

こんな感じです。
https://tsware.jp/tips/tips_689.htm
様のサイトを参照して作っている部分です。

7

新規ブックを開いて、行挿入する場合は、Openメソッドの代わりにAddメソッドを使います。
保存するときにファイル名を指定するようにします。

Sub Accessで新規ブックを開いて行挿入()
    Dim xls As Object
    Set xls = CreateObject("Excel.Application")
    xls.Visible = True
    
    Dim wb As Object 'ワークブックオブジェクト
    Set wb = xls.Workbooks.Add
    
    Dim i As Long, j As Integer
    i = 1
    j = 5
    
    With wb
        .Sheets(1).Rows(21 + i).Resize(j).Insert
        .Save Filename:="C:\Test\Test.xlsx"
        .Close
    End With
    xls.Quit
    Set xls = Nothing
    Set wb = Nothing
End Sub
6

既存ブックを開いて、行を挿入する場合のコード例

Sub Accessで既存ブックを開いて行挿入()
    Dim xls As Object
    Set xls = CreateObject("Excel.Application")
    xls.Visible = True
    
    Dim wb As Object 'ワークブックオブジェクト
    Set wb = xls.Workbooks.Open(Filename:="C:\Test\Test.xlsx")
    
    Dim i As Long, j As Integer
    i = 1
    j = 5
    
    With wb
        .Sheets(1).Rows(21 + i).Resize(j).Insert
        .Save
        .Close
    End With
    xls.Quit
    Set xls = Nothing
    Set wb = Nothing
End Sub

Openメソッドでブックを開きますが、戻り値は開いたブックなのでそれを変数に代入しておいてあとで利用します。
開いたブックの先頭シートに行挿入してます。
行挿入はRowsを使った方がコードがシンプルになります。

5
hatena 2023/07/20 (木) 18:47:55 修正

中略した部分も提示してください。

中略した部分でブックを開いてますか。
それとも新規ブックのシートに代入するのですか。

xls.Range() としてますが、xls(エクセルアプリケーション)はRangeプロパティをもってません。

エクセルアプリケーションのブックのシートがRangeプロパティをもっています。

どのブックのどのシートのセルに代入するかをはっきりさせないとだめです。

エクセルのVBAで、Range()としたときは、ActiveBook.ActiveSheet.Range() ということにエクセルが解釈してくれます。Access君はそのように自動で解釈してくれませんので、きちんと指定してあげないと、Access君は困ってしまいます。

4
hiroton 2023/07/20 (木) 18:37:00 14585@f966d

うまいこと解説してるサイト見つけてペタッとして終わりたかったんですけど見つけられないですねぇ


このような問題を起こさないためには、「アクティブな」というその瞬間によって変わるような参照を使わないようにする必要があります。そのためには、オブジェクトの親子関係をしっかり把握して、最上位の親から目的の子まで、すべてをつなげる必要があります

Range/Cellsの場合

(Excel)Application   :xls = CreateObject("Excel.application")はこのレベル
 └Workbook
  └Worksheet
   └Range / Cells

つまり、xls.Cellsと記述すると「xls.ActiveWorkBook.ActiveSheet.Cells」と同等の結果になります

「アクティブな」参照をしないためにはWorkbookWorksheetを明示してあげればいいので、例えば

xls.Workbooks(1).Worksheets(1).Cells

のような記述が考えられます
また、毎回このような記述は冗長なので、変数で置き換えたり

Dim WS As object
Set WS = xls.Workbooks(1).Worksheets(1)
WS.Cells(~)
Set WS = Nothing

With ~ End Withステートメントを使ったり

With xls.Workbooks(1).Worksheets(1)
    .Cells(~)
End With

すると良いコードになります

3
hiroton 2023/07/20 (木) 17:24:08 14585@f966d

Excelでなら動く

Range(Cells(21 + i, 1), Cells(21 + i + j, 1)).EntireRow.Insert

を、なんやかんやして

xls.Range(xls.Cells(21 + i, 1), xls.Cells(21 + i + j, 1)).EntireRow.Insert

とした場合、このコード部分だけなら動作させることは可能です
つまり、このコードが動くための準備がうまく出来ていません


xlsSet xls = CreateObject("Excel.application")としていますので、EXCELそのものを示します
Application.Range プロパティ (Excel)

アクティブ シートがワークシートでない場合、このプロパティは失敗します。

Application.Cells プロパティ (Excel)

作業中の文書がワークシートでない場合、このプロパティは無効になります。

いつもの難しいMicrosoft記述ですが、つまり、「ユーザーが操作できる状態じゃないとエラーになるよ」「ユーザーが操作できる状態のモノが対象になるよ」ということです


解決策としては、「操作したいシートをアクティブにする」か、「アクティブでないRange/Cellsを対象にする記述をする」のどちらかです。とはいえ、実際に使っているExcel上でマクロを動かすならともかく、「アクティブな状態」というあやふやな状態を対象とする記述はできる限りやらないほうが無難です

2
nokonoko 2023/07/20 (木) 16:27:32 3e2e6@54883 >> 1

試してませんでした。

Sub sample()
Dim i, j As Integer
i = 2
j = 3
Range(Cells(21 + i, 1), Cells(21 + i + j, 1)).EntireRow.Insert
End Sub

実行したところ、23~26行目に行が4行挿入されました。

1
hiroton 2023/07/20 (木) 15:49:15 14585@f966d

そのコード、EXCELなら動くんですか?

8
nokonoko 2023/07/20 (木) 11:31:32 3e2e6@54883

りんご様に提示していただいた方法で無事解決しました。
qd.parametersの行が33行もあって非常に不格好なコードですが、とりあえずレコードセットにはなってくれました。

Hatena様の方法も試してみたのですが、テキストボックス以外のところで、構造を大きくかえなくてはならなくなりそうなので断念しました。

お二方有難うございました。

7
nokonoko 2023/07/20 (木) 08:17:47 3e2e6@54883 >> 6

回答ありがとうございます。
私では思いもよらない方法でした。試してみます。

6

テキストボックスtxt01からtxt20まであって、
製品コードがそのどれかに当てはまるものを抽出しています。

りんごさんの回答の方法でできると思いますが、参考までに別案も提示しておきます。

テキストボックスを複数個配置する代わりに、条件用のテーブルを作成してそれを利用する方法です。

製品コードと同じデータ型のフィールドをもったテーブルを作成します。
それをレコードソースとする帳票フォームを作成します。
そこで、抽出したい製品コードを入力していきます。
帳票フォームですので、新規追加していけば好きなだけ入力できます。

クエリに対象テーブルと抽出条件テーブルを追加して、対象テーブルの製品コードと条件テーブルのフィールドを結合します。

これで、条件テーブルに入力した製品コードのレコードが抽出されます。 パラメータはないので、Parametersの設定も必要ないです。クエリをOpenRecordsetするだけです。

テキストボックスを配置する方法だとテキストボックスの個数に条件数が制限されますが、この方法だと制限なく入力できます。

5
nokonoko 2023/07/19 (水) 17:32:58 3e2e6@54883 >> 3

VBAのほうで、複数回Parametersを使うのですね。トライしてみます。

ありがとうございました。

4
りんご 2023/07/19 (水) 17:05:19 935bc@0e907 >> 3

遠い昔の記憶ですが、こんな感じだったぁしら。

(略)
  qd.Parameters("[Forms]![F_入力]![txt01]") = Forms!F_入力!txt01
  qd.Parameters("[Forms]![F_入力]![txt02]") = Forms!F_入力!txt02
・・・(略)

T‘sWare Access Tips#083

3
nokonoko 2023/07/19 (水) 16:26:33 3e2e6@54883 >> 2

回答ありがとうございました。

テキストボックスtxt01からtxt20まであって、
製品コードがそのどれかに当てはまるものを抽出しています。
おかげで(というか、初歩的なので)
[Forms]![F_入力]![txt01] Or [Forms]![F_入力]![txt02] Or ...
という抽出条件が書かれています。

複数行に分けるというのはどういうことでしょうか

17
ビギナー 2023/07/19 (水) 16:14:58 ddfe5@5dc2d

りんごさん ありがとうございます。データの基が同じ名前のものを参照では上手くいかない事があるかもしれませんね。
最後の”名称変更して”のアドバイスで上手くいきました。感謝です!

2
りんご 2023/07/19 (水) 15:59:54 935bc@0e907

>とっても長いのところが、参照するコントロールが多くて長くなってます。
もし複数のパラメータを1句に詰め込んでいるのであれば、とりあえず複数行に分けましょう。

1
りんご 2023/07/19 (水) 15:52:39 935bc@0e907

1番オーソドックスな解決法
T‘sWare Access Tips#586
最終手段、「クエリ パラメータ」ダイアログボックスを開いて設定した上で、同じコード(パラメータを指定する)を再試行。
T‘sWare Access Tips#542
もし上記リンク失敗の際は、ググって下さい。

16
りんご 2023/07/19 (水) 15:30:44 935bc@0e907 >> 15

 あれこれ作業しているうちに、設定値が変わってしまった可能性があるのかしら。ちょっと、よくわからないです。
 それはさておき、途中でテーブルが増えたりアレンジしたりするようになったら、大概駄目になるので注意が必要です。
 

3
haruki 2023/07/19 (水) 14:03:13 b5deb@a9108

ご回答ありがとうございます。

なるほどです。DMinを使うのですね。
勉強になりました。解決いたしました。

15
ビギナー 2023/07/19 (水) 13:55:36 ddfe5@5dc2d

りんごさん 上手くいきました! ありがとうございます。 科目テーブルを基に名前変えてクエリにしました。そしてそのクエリを基に貸方項目コンボ用のクエリの値集合ソースとすると機能しました。自分では理解できないのですが何がいけなかったのでしょうか?

14
りんご 2023/07/19 (水) 13:24:32 935bc@0e907 >> 13

もう一度聞きますが、『科目』コンボボックスを作って、(違う名称の)『仕訳』コンボボックスをSQLで参照しているのであれば、『仕訳』コンボボックスに名称変更して、『仕訳』コンボボックスをSQL参照するのは、どうですか?

13
ビギナー 2023/07/19 (水) 12:48:17 ddfe5@5dc2d

りんごさん その後試した事はサブファームでのコンボ借方の値集合ソースからメインフォームでの条件を削除してみて(貸方の絞り込みだけに設定)確認したのですが、やはり貸方のグループ絞り込みは出来ませんでした。それで科目グループを借方用と貸方用を用意して各科目に借方グループ、貸方グループ2段階でしてみましたがこれも駄目でした。最後に科目テーブルを丸々コピーし借方用、貸方用に分けて試すとグループによる絞り込みは上手くいきました。理由は分からないのですが1つのレコードに同じ項目からの参照は駄目みたいです。科目テーブルを同じ内容で2つ作成するしかなさそうです。

8
名前なし 2023/07/19 (水) 11:26:04 7a00e@5b06d >> 6

セーフモードで起動し、新規ファイルは作成できるようになりました。ノートに access がありますので、過去作成のファイルは利用できます。
これまででで判明したこと、OSを修復すると破損個所が見つかりました。デスクトップ画面でソフトのアイコンを右クリックし「管理者として実行」を行うとアクセスのアイコンのみ反応しません。このマシンでアクセスを作成するときに(トラストセンター)なるものをいらっていましたので!これが原因?
アクセスの問題としてとらえることを、いったん終了としますのでこの質問を終了とさせてください。
判明の折には、報告させていだ抱きます。

7

新規ファイルの作成ができないとは、どういう状況ですか。
Accessがインストールされてなくて、Access Runtimeがインストールされているということですか。
であるなら、Accessがインストールされているマシンへコピーしてそこで作成してください。

12
りんご 2023/07/18 (火) 17:15:02 935bc@0e907 >> 11

どちらかに統一すると、何か変わりますか?
コンボ貸方の科目グループ選択
コンボ貸方の仕訳グループ選択

11
ビギナー 2023/07/18 (火) 16:37:05 ddfe5@5dc2d

再度添付します。画像1
貸方パラメータの方はスクショしても何故かこれしかコピー出来ませんでした。各SQLは一番最初に記述した通りです。

6
初老の人 2023/07/18 (火) 16:08:56 cfdf6@5b06d >> 4

早速の回答、ありがとうございます。


まずは修復/最適化を実行してみてください。


セイフモードで起動し、(修復/最適化)を行っても同じ現象です。
言い忘れていましたが、アクセスをクリックするとタスクバーにアクセスのアイコンは常に出ます。
エクセ,ワードは通常の起動をしています。


データベースファイルを新規作成


新規作成は、このマシンではできません。
よろしくお願いいたします。

10
hiroton 2023/07/18 (火) 16:01:31 da7ce@f966d >> 5

一応補足しておくと、hirotonがここでいう「謎のバグ」とはいわゆる「mdbが壊れちゃった」状態のことです
無理な制御を試してエラーで強制停止したとか、強制終了でACCESSを終了させたとか、内部的に不整合が起きているであろう状態で保存されてしまうと訳の分からない動作をする(してほしい動作が行われない)ということが起こる場合があります。いつ不整合が起きたのかもわからなければ、いつ、どこで不具合が発生するかもわかりません

「新規でデータベースを作成して、全く同じフォーム(モジュール)を作成したら問題なく動いた」という、完全に原因不明の不具合となります

9
りんご 2023/07/18 (火) 16:00:55 935bc@0e907 >> 8

 パラメータの入力ダイアログボックスは、借方じゃなくてもう1つの貸方のほう。
 そして、メイン/サブフォームとサブフォーム開いた状態の画面コピーではなくて、ちゃんとプロパティシート『名前: コンボ貸方の仕訳グループ選択』が確認できる画面コピーでない限り、全く無意味です。

8
ビギナー 2023/07/18 (火) 15:52:32 ddfe5@5dc2d

色々情報不足ですみません。メイン/サブフォームとサブフォーム開いた状態の画面コピー添付します。
サブフォームの方はパラメータを入れると表示されます。画像1

5
初老の人 2023/07/18 (火) 15:42:25 cfdf6@5b06d >> 2

Win11のアップグレードは頻繁に行っています。初期の時は作動していましたので最近のアップグレードで問題が発生?

4

まずは修復/最適化を実行してみてください。
それで改善しないなら、
データベースファイルを新規作成して、そこに現在のファイルからすべてのオブジェクトをインポートしてそれを使うようにしてみてください。