たびたび失礼します。
Dim xls as Object
Dim i,j as integer
Set xls = CreateObject("Excel.application")
(中略)
xls.Range(cells(21+i , 1), cells(21+i+j , 1).entirerow.Insert
やりたいことは、21+i行目からj行分の行を挿入することです。
「オブジェクトは、このプロパティまたはメソッドをサポートしていません」となってしまいます。
AccessにCellsがないということだと思いますが、
xls.Range(xls.cells(21+i , 1), xls.cells(21+i+j , 1).entirerow.Insert
としても、変化がありません。
Accessではどうすればよいのでしょうか
そのコード、EXCELなら動くんですか?
試してませんでした。
実行したところ、23~26行目に行が4行挿入されました。
Excelでなら動く
を、なんやかんやして
とした場合、このコード部分だけなら動作させることは可能です
つまり、このコードが動くための準備がうまく出来ていません
xls
はSet xls = CreateObject("Excel.application")
としていますので、EXCELそのものを示しますApplication.Range プロパティ (Excel)
Application.Cells プロパティ (Excel)
いつもの難しいMicrosoft記述ですが、つまり、「ユーザーが操作できる状態じゃないとエラーになるよ」「ユーザーが操作できる状態のモノが対象になるよ」ということです
解決策としては、「操作したいシートをアクティブにする」か、「アクティブでないRange/Cellsを対象にする記述をする」のどちらかです。とはいえ、実際に使っているExcel上でマクロを動かすならともかく、「アクティブな状態」というあやふやな状態を対象とする記述はできる限りやらないほうが無難です
うまいこと解説してるサイト見つけてペタッとして終わりたかったんですけど見つけられないですねぇ
このような問題を起こさないためには、「アクティブな」というその瞬間によって変わるような参照を使わないようにする必要があります。そのためには、オブジェクトの親子関係をしっかり把握して、最上位の親から目的の子まで、すべてをつなげる必要があります
Range
/Cells
の場合つまり、
xls.Cells
と記述すると「xls.ActiveWorkBook.ActiveSheet.Cells」と同等の結果になります「アクティブな」参照をしないためには
Workbook
とWorksheet
を明示してあげればいいので、例えばのような記述が考えられます
また、毎回このような記述は冗長なので、変数で置き換えたり
With ~ End With
ステートメントを使ったりすると良いコードになります
中略した部分も提示してください。
中略した部分でブックを開いてますか。
それとも新規ブックのシートに代入するのですか。
xls.Range() としてますが、xls(エクセルアプリケーション)はRangeプロパティをもってません。
エクセルアプリケーションのブックのシートがRangeプロパティをもっています。
どのブックのどのシートのセルに代入するかをはっきりさせないとだめです。
エクセルのVBAで、Range()としたときは、ActiveBook.ActiveSheet.Range() ということにエクセルが解釈してくれます。Access君はそのように自動で解釈してくれませんので、きちんと指定してあげないと、Access君は困ってしまいます。
既存ブックを開いて、行を挿入する場合のコード例
Openメソッドでブックを開きますが、戻り値は開いたブックなのでそれを変数に代入しておいてあとで利用します。
開いたブックの先頭シートに行挿入してます。
行挿入はRowsを使った方がコードがシンプルになります。
新規ブックを開いて、行挿入する場合は、Openメソッドの代わりにAddメソッドを使います。
保存するときにファイル名を指定するようにします。
お二方回答ありがとうございます。
回答を見たばかりなので、内容確認できてはおりません。
こんな感じです。
https://tsware.jp/tips/tips_689.htm
様のサイトを参照して作っている部分です。
まず、回答の前に、一言。
コードの一部の抜粋を提示するより、可能ならば Sub から End Sub まですべて提示した方が話がはやいでしょう。
もし、コードが提示するには長すぎるなら、処理を複数のサブルーチンに分割することを検討した方がいいでしょう。
今回も、結局リンク先のコードをみて類推して回答することになりますが、認識違いで無駄なやりとりになる可能性もあります。
こちらで、リンク先のコードと提示のコードからサンプルを作成して実験したところ、下記を修正したら正常に動作しました。
ようは不足していた
)
を追加しただけです。ただし、この修正前のコードでは構文エラーになり実行すらできませんので、
というようなエラーにはなりませんので、提示されていない他の部分に原因があるでしょう。
ということで、やはりコード全体を提示してください。
ご指摘ありがとうございます。
そのままでは3000字を越えてしまうので、少し検討します。
明らかに不要なところを除きました。
実行時に同様のエラーが出ます。
書き込みがある度、コードが変わりますね
落ち着いて、コピペをしてください
xls.Range(xls.cesll(21 + intNumRow, 1), xls.cells(21 + intNumRow + intGNumRoW, 2)).entirerow .Insert
失礼いたしました。
もともとのコードがぐちゃぐちゃで、そのまま貼り付けるにははばかられるようなものだったので、
修正をして貼り付けたときに、ミスが出たのだと思います。
ざっと見た感じではコード自体に問題はなさそうです。
(もっとスマートな書き方かあるかもということは置いておいて)
とりあえずうまくいかないとき、原因を特定するためのデバッグ作業をしてみましょう。
まず、
On Error GoTo Err_Handler
はコメントアウトしておきましょう。これがあるとどこでエラーがある分かりません。
次に、
としてエクセルを表示させ、画面の再描画停止をやめましょう。
これでエクセル上での操作を目で確認できます。
そのうえで1行ずつステップ実行して動作を確認しつつ、どこでどのようなエラーが出るのか確認しましょう。ステップ実行 は下記リンクを参考にしてください。
デバッグの基本 – ステップ実行 | ExcelVBA入門 自宅でプログラミング
このデバッグ作業をして、どの行でどのようなエラーがでるのか教えてください。
ありがとうございます。
コメントアウトなどの処置をして、検証しました。
のところで、「実行時エラー‘438‘: オブジェクトは、このプロパティまたはメソッドをサポートしていません。」が出ます。
その前までは、望んでいるような結果が出ています。
失礼しました
Cesllになってました。
直したら、動きました。
こんなくだらないことに、たくさん回答いただき、大変申し訳ないです。
Hiroton様もありがとうございました。
ほかに問題がないか後で検証します。
11のところで抜粋したものについてはCesllになぜかなっていましたが、
抜粋前の本コードのほうはCellsであっていましたが、hiroton様指摘の通り、entirerowの後にスペースがあることによってエラーが出たことがわかりました。
いずれにせよ、当方の非常に初歩的なミス、プラスおっちょこちょいでした。
お二方には改めてお礼を申し上げます。
今後は、このようなことがないように、利用させていただきます。