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
まず、回答の前に、一言。
コードの一部の抜粋を提示するより、可能ならば Sub から End Sub まですべて提示した方が話がはやいでしょう。
もし、コードが提示するには長すぎるなら、処理を複数のサブルーチンに分割することを検討した方がいいでしょう。
今回も、結局リンク先のコードをみて類推して回答することになりますが、認識違いで無駄なやりとりになる可能性もあります。
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
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
失礼しました
Cesllになってました。
直したら、動きました。
こんなくだらないことに、たくさん回答いただき、大変申し訳ないです。
Hiroton様もありがとうございました。
ほかに問題がないか後で検証します。
ありがとうございます。
コメントアウトなどの処置をして、検証しました。
のところで、「実行時エラー‘438‘: オブジェクトは、このプロパティまたはメソッドをサポートしていません。」が出ます。
その前までは、望んでいるような結果が出ています。
ざっと見た感じではコード自体に問題はなさそうです。
(もっとスマートな書き方かあるかもということは置いておいて)
とりあえずうまくいかないとき、原因を特定するためのデバッグ作業をしてみましょう。
まず、
On Error GoTo Err_Handler
はコメントアウトしておきましょう。これがあるとどこでエラーがある分かりません。
次に、
としてエクセルを表示させ、画面の再描画停止をやめましょう。
これでエクセル上での操作を目で確認できます。
そのうえで1行ずつステップ実行して動作を確認しつつ、どこでどのようなエラーが出るのか確認しましょう。ステップ実行 は下記リンクを参考にしてください。
デバッグの基本 – ステップ実行 | ExcelVBA入門 自宅でプログラミング
このデバッグ作業をして、どの行でどのようなエラーがでるのか教えてください。
失礼いたしました。
もともとのコードがぐちゃぐちゃで、そのまま貼り付けるにははばかられるようなものだったので、
修正をして貼り付けたときに、ミスが出たのだと思います。
書き込みがある度、コードが変わりますね
落ち着いて、コピペをしてください
xls.Range(xls.cesll(21 + intNumRow, 1), xls.cells(21 + intNumRow + intGNumRoW, 2)).entirerow .Insert
明らかに不要なところを除きました。
実行時に同様のエラーが出ます。
ご指摘ありがとうございます。
そのままでは3000字を越えてしまうので、少し検討します。
まず、回答の前に、一言。
コードの一部の抜粋を提示するより、可能ならば Sub から End Sub まですべて提示した方が話がはやいでしょう。
もし、コードが提示するには長すぎるなら、処理を複数のサブルーチンに分割することを検討した方がいいでしょう。
今回も、結局リンク先のコードをみて類推して回答することになりますが、認識違いで無駄なやりとりになる可能性もあります。
こちらで、リンク先のコードと提示のコードからサンプルを作成して実験したところ、下記を修正したら正常に動作しました。
ようは不足していた
)
を追加しただけです。ただし、この修正前のコードでは構文エラーになり実行すらできませんので、
というようなエラーにはなりませんので、提示されていない他の部分に原因があるでしょう。
ということで、やはりコード全体を提示してください。
お二方回答ありがとうございます。
回答を見たばかりなので、内容確認できてはおりません。
こんな感じです。
https://tsware.jp/tips/tips_689.htm
様のサイトを参照して作っている部分です。
新規ブックを開いて、行挿入する場合は、Openメソッドの代わりにAddメソッドを使います。
保存するときにファイル名を指定するようにします。
既存ブックを開いて、行を挿入する場合のコード例
Openメソッドでブックを開きますが、戻り値は開いたブックなのでそれを変数に代入しておいてあとで利用します。
開いたブックの先頭シートに行挿入してます。
行挿入はRowsを使った方がコードがシンプルになります。
中略した部分も提示してください。
中略した部分でブックを開いてますか。
それとも新規ブックのシートに代入するのですか。
xls.Range() としてますが、xls(エクセルアプリケーション)はRangeプロパティをもってません。
エクセルアプリケーションのブックのシートがRangeプロパティをもっています。
どのブックのどのシートのセルに代入するかをはっきりさせないとだめです。
エクセルのVBAで、Range()としたときは、ActiveBook.ActiveSheet.Range() ということにエクセルが解釈してくれます。Access君はそのように自動で解釈してくれませんので、きちんと指定してあげないと、Access君は困ってしまいます。
うまいこと解説してるサイト見つけてペタッとして終わりたかったんですけど見つけられないですねぇ
このような問題を起こさないためには、「アクティブな」というその瞬間によって変わるような参照を使わないようにする必要があります。そのためには、オブジェクトの親子関係をしっかり把握して、最上位の親から目的の子まで、すべてをつなげる必要があります
Range
/Cells
の場合つまり、
xls.Cells
と記述すると「xls.ActiveWorkBook.ActiveSheet.Cells」と同等の結果になります「アクティブな」参照をしないためには
Workbook
とWorksheet
を明示してあげればいいので、例えばのような記述が考えられます
また、毎回このような記述は冗長なので、変数で置き換えたり
With ~ End With
ステートメントを使ったりすると良いコードになります
Excelでなら動く
を、なんやかんやして
とした場合、このコード部分だけなら動作させることは可能です
つまり、このコードが動くための準備がうまく出来ていません
xls
はSet xls = CreateObject("Excel.application")
としていますので、EXCELそのものを示しますApplication.Range プロパティ (Excel)
Application.Cells プロパティ (Excel)
いつもの難しいMicrosoft記述ですが、つまり、「ユーザーが操作できる状態じゃないとエラーになるよ」「ユーザーが操作できる状態のモノが対象になるよ」ということです
解決策としては、「操作したいシートをアクティブにする」か、「アクティブでないRange/Cellsを対象にする記述をする」のどちらかです。とはいえ、実際に使っているExcel上でマクロを動かすならともかく、「アクティブな状態」というあやふやな状態を対象とする記述はできる限りやらないほうが無難です
試してませんでした。
実行したところ、23~26行目に行が4行挿入されました。
そのコード、EXCELなら動くんですか?
りんご様に提示していただいた方法で無事解決しました。
qd.parametersの行が33行もあって非常に不格好なコードですが、とりあえずレコードセットにはなってくれました。
Hatena様の方法も試してみたのですが、テキストボックス以外のところで、構造を大きくかえなくてはならなくなりそうなので断念しました。
お二方有難うございました。
回答ありがとうございます。
私では思いもよらない方法でした。試してみます。
りんごさんの回答の方法でできると思いますが、参考までに別案も提示しておきます。
テキストボックスを複数個配置する代わりに、条件用のテーブルを作成してそれを利用する方法です。
製品コードと同じデータ型のフィールドをもったテーブルを作成します。
それをレコードソースとする帳票フォームを作成します。
そこで、抽出したい製品コードを入力していきます。
帳票フォームですので、新規追加していけば好きなだけ入力できます。
クエリに対象テーブルと抽出条件テーブルを追加して、対象テーブルの製品コードと条件テーブルのフィールドを結合します。
これで、条件テーブルに入力した製品コードのレコードが抽出されます。 パラメータはないので、Parametersの設定も必要ないです。クエリをOpenRecordsetするだけです。
テキストボックスを配置する方法だとテキストボックスの個数に条件数が制限されますが、この方法だと制限なく入力できます。
VBAのほうで、複数回Parametersを使うのですね。トライしてみます。
ありがとうございました。
遠い昔の記憶ですが、こんな感じだったぁしら。
T‘sWare Access Tips#083
回答ありがとうございました。
テキストボックスtxt01からtxt20まであって、
製品コードがそのどれかに当てはまるものを抽出しています。
おかげで(というか、初歩的なので)
[Forms]![F_入力]![txt01] Or [Forms]![F_入力]![txt02] Or ...
という抽出条件が書かれています。
複数行に分けるというのはどういうことでしょうか
りんごさん ありがとうございます。データの基が同じ名前のものを参照では上手くいかない事があるかもしれませんね。
最後の”名称変更して”のアドバイスで上手くいきました。感謝です!
>とっても長いのところが、参照するコントロールが多くて長くなってます。
もし複数のパラメータを1句に詰め込んでいるのであれば、とりあえず複数行に分けましょう。
1番オーソドックスな解決法
T‘sWare Access Tips#586
最終手段、「クエリ パラメータ」ダイアログボックスを開いて設定した上で、同じコード(パラメータを指定する)を再試行。
T‘sWare Access Tips#542
もし上記リンク失敗の際は、ググって下さい。
あれこれ作業しているうちに、設定値が変わってしまった可能性があるのかしら。ちょっと、よくわからないです。
それはさておき、途中でテーブルが増えたりアレンジしたりするようになったら、大概駄目になるので注意が必要です。
ご回答ありがとうございます。
なるほどです。DMinを使うのですね。
勉強になりました。解決いたしました。
りんごさん 上手くいきました! ありがとうございます。 科目テーブルを基に名前変えてクエリにしました。そしてそのクエリを基に貸方項目コンボ用のクエリの値集合ソースとすると機能しました。自分では理解できないのですが何がいけなかったのでしょうか?
もう一度聞きますが、『科目』コンボボックスを作って、(違う名称の)『仕訳』コンボボックスをSQLで参照しているのであれば、『仕訳』コンボボックスに名称変更して、『仕訳』コンボボックスをSQL参照するのは、どうですか?
りんごさん その後試した事はサブファームでのコンボ借方の値集合ソースからメインフォームでの条件を削除してみて(貸方の絞り込みだけに設定)確認したのですが、やはり貸方のグループ絞り込みは出来ませんでした。それで科目グループを借方用と貸方用を用意して各科目に借方グループ、貸方グループ2段階でしてみましたがこれも駄目でした。最後に科目テーブルを丸々コピーし借方用、貸方用に分けて試すとグループによる絞り込みは上手くいきました。理由は分からないのですが1つのレコードに同じ項目からの参照は駄目みたいです。科目テーブルを同じ内容で2つ作成するしかなさそうです。
セーフモードで起動し、新規ファイルは作成できるようになりました。ノートに access がありますので、過去作成のファイルは利用できます。
これまででで判明したこと、OSを修復すると破損個所が見つかりました。デスクトップ画面でソフトのアイコンを右クリックし「管理者として実行」を行うとアクセスのアイコンのみ反応しません。このマシンでアクセスを作成するときに(トラストセンター)なるものをいらっていましたので!これが原因?
アクセスの問題としてとらえることを、いったん終了としますのでこの質問を終了とさせてください。
判明の折には、報告させていだ抱きます。
新規ファイルの作成ができないとは、どういう状況ですか。
Accessがインストールされてなくて、Access Runtimeがインストールされているということですか。
であるなら、Accessがインストールされているマシンへコピーしてそこで作成してください。
どちらかに統一すると、何か変わりますか?
コンボ貸方の科目グループ選択
コンボ貸方の仕訳グループ選択
再度添付します。
貸方パラメータの方はスクショしても何故かこれしかコピー出来ませんでした。各SQLは一番最初に記述した通りです。
早速の回答、ありがとうございます。
まずは修復/最適化を実行してみてください。
セイフモードで起動し、(修復/最適化)を行っても同じ現象です。
言い忘れていましたが、アクセスをクリックするとタスクバーにアクセスのアイコンは常に出ます。
エクセ,ワードは通常の起動をしています。
データベースファイルを新規作成
新規作成は、このマシンではできません。
よろしくお願いいたします。
一応補足しておくと、hirotonがここでいう「謎のバグ」とはいわゆる「mdbが壊れちゃった」状態のことです
無理な制御を試してエラーで強制停止したとか、強制終了でACCESSを終了させたとか、内部的に不整合が起きているであろう状態で保存されてしまうと訳の分からない動作をする(してほしい動作が行われない)ということが起こる場合があります。いつ不整合が起きたのかもわからなければ、いつ、どこで不具合が発生するかもわかりません
「新規でデータベースを作成して、全く同じフォーム(モジュール)を作成したら問題なく動いた」という、完全に原因不明の不具合となります
パラメータの入力ダイアログボックスは、借方じゃなくてもう1つの貸方のほう。
そして、メイン/サブフォームとサブフォーム開いた状態の画面コピーではなくて、ちゃんとプロパティシート『名前: コンボ貸方の仕訳グループ選択』が確認できる画面コピーでない限り、全く無意味です。
色々情報不足ですみません。メイン/サブフォームとサブフォーム開いた状態の画面コピー添付します。
サブフォームの方はパラメータを入れると表示されます。
Win11のアップグレードは頻繁に行っています。初期の時は作動していましたので最近のアップグレードで問題が発生?
まずは修復/最適化を実行してみてください。
それで改善しないなら、
データベースファイルを新規作成して、そこに現在のファイルからすべてのオブジェクトをインポートしてそれを使うようにしてみてください。