エクセルマクロ オンライン講座コメント紹介

  • このエントリーをはてなブックマークに追加
コメント紹介

エクセルマクロオンライン講座への質問とその回答から

[7913] 2017-04-09 09:37:11 平吹 敦史さんからの投稿です。

お世話になっております。

発展編2テキストP18のChap02-11の問題について質問です。
Sub GetZangyoList_Normal()を配列関数を使わずに、他のやり方をいろいろ試しています。

下記①と②があります。
①は問題なく動きます。
②は下記コードでエラーになります。
wsZ1.Range("B2:14").Offset(, lnretu).Value _
= ws.Range("C3:C15").Value
エラーは、「実行時エラー’1004’」
'Range'メソッドは失敗しました:'Worksheet'オブジェクト
となります。

何らかのルール違反をしているかと思うのですが、わかりませんでした。
ご教授願います。


Option Explicit
Dim lnretu As Long

Sub Sample1() '配列関数を使わないパターン
Application.ScreenUpdating = False
Dim lnCt As Long
lnretu = 0
For lnCt = 1 To Worksheets.Count
Worksheets(lnCt).Activate
If Left(ActiveSheet.Name, 2) <> "残業" Then
Sample2
End If
Next
Worksheets("残業1").Activate
Application.ScreenUpdating = True
End Sub

Sub Sample2() '配列関数を使わないパターン
Application.ScreenUpdating = False
Dim wsZ4 As Worksheet
Set wsZ4 = Worksheets("残業1")

With wsZ4.Range("B1")
.Offset(, lnretu).Value = ActiveSheet.Name
wsZ4.Range("B2:B14").Offset(, lnretu).Value _
= ActiveSheet.Range("C3:C15").Value
lnretu = lnretu + 1
End With
wsZ4.Activate
Application.ScreenUpdating = True
End Sub


Sub Sample3()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim wsZ1 As Worksheet
Set wsZ1 = Worksheets("残業1")
Dim lnretu As Long

lnretu = 0
For Each ws In Worksheets
If Left(ws.Name, 2) <> "残業" Then
wsZ1.Range("B1").Offset(, lnretu).Value = ws.Name
wsZ1.Range("B2:14").Offset(, lnretu).Value _
= ws.Range("C3:C15").Value・・・・ここで、エラー
lnretu = lnretu + 1
End If
Next
End Sub

 


[7915] 2017-04-09 16:38:26 平吹 敦史さんからの投稿です。

お世話になっております。

以下質問、無視してください。
恥ずかしながら、単純な範囲指定の記入ミスでした・・・

wsZ1.Range("B2:14") → wsZ1.Range("B2:B14")

ただ、配列関数を使わないやり方として、①、②はどうなのか、
評価がほしいので、コメントをお願いします。

>お世話になっております。
>
>発展編2テキストP18のChap02-11の問題について質問です。
>Sub GetZangyoList_Normal()を配列関数を使わずに、他のやり方をいろいろ試しています。
>
>下記①と②があります。
>①は問題なく動きます。
>②は下記コードでエラーになります。
> wsZ1.Range("B2:14").Offset(, lnretu).Value _
> = ws.Range("C3:C15").Value
>エラーは、「実行時エラー’1004’」
>'Range'メソッドは失敗しました:'Worksheet'オブジェクト
>となります。
>
>何らかのルール違反をしているかと思うのですが、わかりませんでした。
>ご教授願います。
>
>①
>Option Explicit
>Dim lnretu As Long
>
>Sub Sample1() '配列関数を使わないパターン
> Application.ScreenUpdating = False
> Dim lnCt As Long
> lnretu = 0
> For lnCt = 1 To Worksheets.Count
> Worksheets(lnCt).Activate
> If Left(ActiveSheet.Name, 2) <> "残業" Then
> Sample2
> End If
> Next
> Worksheets("残業1").Activate
> Application.ScreenUpdating = True
>End Sub
>
>Sub Sample2() '配列関数を使わないパターン
> Application.ScreenUpdating = False
> Dim wsZ4 As Worksheet
> Set wsZ4 = Worksheets("残業1")
>
> With wsZ4.Range("B1")
> .Offset(, lnretu).Value = ActiveSheet.Name
> wsZ4.Range("B2:B14").Offset(, lnretu).Value _
> = ActiveSheet.Range("C3:C15").Value
> lnretu = lnretu + 1
> End With
> wsZ4.Activate
> Application.ScreenUpdating = True
>End Sub
>
>②
>Sub Sample3()
> Application.ScreenUpdating = False
> Dim ws As Worksheet
> Dim wsZ1 As Worksheet
> Set wsZ1 = Worksheets("残業1")
> Dim lnretu As Long
>
> lnretu = 0
> For Each ws In Worksheets
> If Left(ws.Name, 2) <> "残業" Then
> wsZ1.Range("B1").Offset(, lnretu).Value = ws.Name
> wsZ1.Range("B2:14").Offset(, lnretu).Value _
> = ws.Range("C3:C15").Value・・・・ここで、エラー
> lnretu = lnretu + 1
> End If
> Next
>End Sub
>

 


[7920] 2017-04-10 09:27:28 小川慶一さんからの投稿です。

平吹 敦史 さん:

wsZ1.Range("B2:14").Offset(, lnretu).Value _
= ws.Range("C3:C15").Value・・・・ここで、エラー



"B2:14" の部分の問題に気づかないままでテストを進めるとしたら。
僕なら、エラーが出た状態で中断モードにし、以下を順に試しますね。

[1]
wsZ1.Range("B2:14").Offset(, lnretu).Value
の Value の上にマウスポインタを持ってきて、表示内容を確認する。

おそらく、その段階でエラーに気づくものと思います。
「右辺はともあれ、少なくとも、左辺で何らかの問題が起きている」と、ということがここで分かる。

[2]
同様に、 Inretu の上にマウスポインタを持ってきて、表示内容を確認する。

これは表示される。0だから、問題なさそう。OK。

[3]
Debug.Print wsZ4.Name
をイミディエイトウィンドウ実行し、イミディエイトウィンドウにシート名が表示されるかを調べる。

「残業1」と出力される。これはOK。

[4]
「ということは、以下が怪しそうだ。」と気づく。
Range("B2:14")

基礎編でテストの方法について学びましたね。
それは、こういう問題が起きたときに、いちいち人に聞かないでも自分で解決できるようになるためです。

この問題を自分でテストを行って解決できないとしたら、やはり経験不足です。
別件でも書きましたが、演習&実務での活用を。

基本的な概念を演習を通じてしっかりと自分のモノにしてください。

「自分のモノにする」というのは、より具体的に言うと、「問題を見た瞬間に身体が自動反応して、頭をほとんど使わないでマクロを書ききれる」というくらいにの域に到達することです。
「思考して問題を解いている」というより、「身体が勝手に問題を解いてくれる」というくらいの状態ですね。

それはもちろん、マクロを書く過程で途中でエラーが出たときにも半ば無意識に修正できる状態です。
数学の試験で計算用紙に計算を書き込んでいるとき、間違いに気づくと、無意識に消しゴムで文字を消して書き直します。そのときに人は半ば無意識に消しゴムを使っています。
それと同じくらいに、テストも「身体が勝手にやってくれる」レベルを目指します。

基礎編~発展編1くらいの演習であれば、問題があったとしてもそのくらいに無意識な動作でマクロを書けるようになっているべきです。
(ですし、基礎編~発展編1をそのレベルで習得できれば、発展編2の知識なしでも、実務で今まで以上にガンガンマクロを書けます)

そこを抜かして新しい概念をどんどん頭に詰め込もうとするのは、かけ算九九もうろ覚えなままで、分数の通分約分について学ぶようなものです。

高度な抽象概念の理解と実装を可能にするのは、基礎的な計算力、問題解決力です。


>①、②はどうなのか、評価がほしいので、コメントをお願いします。

[1]については、、とりあえず、動けばOKです。
本当は、「複数のプロシージャで Worksheets("残業1") という表記が出て来ることでプログラム全体が冗長かつメンテナンス性が落ちている」とか、「.Activate は使いたくない」とか、 「Sample1 のループ直後に一覧用のシートをアクティブにしているなら、 Sample2 でいちいち同シートをアクティブにする必要はない」とか、「発展編2まで学習が進んでいるなら Sample1 が Sample2 を呼び出すときに引数つきプロシージャにすれば良いのでは?」とかいろいろあるのですが。。このところのやりとりから想像される今の理解力&実装力と、今回いただいたサンプルコードの中途半端な品質からするに、今の平吹さんには「ではどうすればよい?」というところまで話すにはまだ早いように思えるので、指摘はしません。
(と言いつつ、指摘していますが)

とはいえひとつだけコメントすると、変数をハンガリアン記法で命名するときには、一般に、データ型を示すprefixは、小文字にします。
あとは、くり返しますが、過去の演習を何度もくり返し自力で解いてください。

[2]については、添削を希望されるようでしたら、きちんと動作するプログラムを再提出してください。

 


まずはここから!スマホでも学べる無料動画講座

今なら先着30名限定で無料!定価4,800円の、初心者のためのエクセルマクロ動画講座。
  1. Excel 97~Excel 2016まですべて対応。動画本数20本、総再生時間2時間44分53秒
  2. PC, Mac, iPhone, iPad, Androidのお好みの環境で、いつでも好きなときに学べます。
2004年から10年間述べ3,000名以上に実施した研修の経験と実績を集約した講座です。
いますぐ無料で試してください。

トップへ