発展編1 フォローメールセミナー 第7回

この講座は有料講座です。
講座の購入後ご覧になれます。

ログインアカウントの新規作成

解説

発展編1のフォローメールセミナー第7回のフィードバック記入ページです。 【動画はありません】個別ページにて重要事項満載のフォローメールをお読みいただけます。

この教材についての過去の質問・感想

12316 : 小川慶一の回答 (2020-07-31 08:25:31)

受講生 さん:

おはようございます。

> 罫線のマクロを呼び出すタイミング、難しかったです。
> 何度かステップインで確認してなんとかできました。

以下の動画の9:38-
商品ごと、年ごとの販売額合計をピボットテーブルのように出力する(その2-1)
https://online.pc5bai.com/movie/index/86/1277

以下の動画の冒頭
商品ごと、年ごとの販売額合計をピボットテーブルのように出力する(その2-2)
https://online.pc5bai.com/Movie/index/86/1279

でお伝えしているものと、基本の構造は同じです。
そういうつもりで、上述の課題を解き、それから再度この課題をやってみてください。

> 過去のコメント欄を読むのも勉強になりますね。

ですね。
過去のやりとりは、ちょうどそのページの課題くらいが適切だった方からの質問やそれにあわせた回答をしています。


12315 : 受講生さんのコメント (2020-07-31 00:59:22)

お世話になります。

罫線のマクロを呼び出すタイミング、難しかったです。
何度かステップインで確認してなんとかできました。

過去のコメント欄を読むのも勉強になりますね。


10128 : 小川慶一の回答 (2018-06-19 13:37:10)

受講生さん:

まずは動けばOKですよ。

インデントには気をつけましょう。
以下参照ください。

If shFm.Range("G" & lnFm).Value > 0 Then
    shTo.Range("I" & lnTo).Value = shFm.Range("G" & lnFm).Value
    	'↓インデント多すぎです。
        If lnTo = 16 Then
            shTo.Range("K" & lnTo).Value = shTo.Range("I" & lnTo).Value
        Else
            shTo.Range("K" & lnTo).Value = shTo.Range("K" & lnTo - 1).Value + _
                                                                shTo.Range("I" & lnTo).Value
        End If
Else
    shTo.Range("J" & lnTo).Value = shFm.Range("G" & lnFm).Value
    	'↓インデント多すぎです。
        If lnTo = 16 Then
            shTo.Range("K" & lnTo).Value = shTo.Range("J" & lnTo).Value
        Else
            shTo.Range("K" & lnTo).Value = shTo.Range("K" & lnTo - 1).Value + _
                                                                shTo.Range("J" & lnTo).Value
        End If
End If



> 簿記の発想で行ってしまうので、どうしても頭が固くなっています。
> 私が書いた残高計算方法では、
> ¥FollowMailSeminor_07.txt(添付ファイル)
> のように、残高=前残高+借方ー貸方 という発想になってしまいます。
>  小川先生のように、より自由な発想法が出来れば良いのですが、
> 中々うまくいきません。
>
>


10119 : 横山 知明さんのコメント (2018-06-16 08:17:54)

簿記の発想で行ってしまうので、どうしても頭が固くなっています。
私が書いた残高計算方法では、
¥FollowMailSeminor_07.txt(添付ファイル)
のように、残高=前残高+借方ー貸方 という発想になってしまいます。
 小川先生のように、より自由な発想法が出来れば良いのですが、
中々うまくいきません。


10062 : 小川慶一の回答 (2018-05-30 09:55:36)

HKさん:

>残高の計算も、変数を使用して、条件分岐をしなくてもいいように作ってみました。
>(条件分岐を考えるのがめんどくさいのでなるべく避けるように作ってしまいます)

おもしろいですね。

> 先生のやり方も出来るように練習したいと思います。

	ループ始まり
		条件分岐
			最初に条件を満たしたときは何もしない
		通常処理
	ループ終わり
	終了後の処理


というのは、マスターしておくと利便性の高いパターンです。
ぜひ、練習しておいてください。

あと、いただいたマクロだと、メインの処理前後の並べ替えがないので、そこ注意しましょう。


10059 : HKさんのコメント (2018-05-29 13:11:41)

私も9411でコメントされている受講生さんと同じように、自分で作ったプログラムでは罫線を引く作業は別のサブプロシージャを作成しました。

また、残高の計算も、変数を使用して、条件分岐をしなくてもいいように作ってみました。(条件分岐を考えるのがめんどくさいのでなるべく避けるように作ってしまいます)

先生のやり方も出来るように練習したいと思います。

Sub GetNames_Final()
    DeleteSheets_Fin
    
    Dim lnGyo As Long
    Dim lnGyoMx As Long
    Dim wsMain As Worksheet
    Dim stCompany As String
    Dim wsSaki As Worksheet
    Dim dt As Date
    Dim lnSaki As Long
    Dim lnZandaka As Long
    
    Set wsMain = Worksheets("main")
    lnGyoMx = wsMain.Range("B" & wsMain.Rows.Count).End(xlUp).Row
    
    For lnGyo = 2 To lnGyoMx
        If stCompany <> wsMain.Range("B" & lnGyo).Value Then
            stCompany = wsMain.Range("B" & lnGyo).Value
'            Debug.Print wsMain.Range("B" & lnGyo).Value
            Worksheets("main1").Copy after:=Worksheets(Worksheets.Count)
            Set wsSaki = Worksheets(Worksheets.Count)
            wsSaki.Name = stCompany
            lnSaki = 16
            lnZandaka = 0
        End If
        
        wsSaki.Range("H" & lnSaki).Value = wsMain.Range("F" & lnGyo).Value
        wsSaki.Range("E" & lnSaki).Value = wsMain.Range("D" & lnGyo).Value
        wsSaki.Range("F" & lnSaki).Value = wsMain.Range("E" & lnGyo).Value
        If wsMain.Range("G" & lnGyo).Value > 0 Then
            wsSaki.Range("I" & lnSaki).Value = wsMain.Range("G" & lnGyo).Value
        Else
            wsSaki.Range("J" & lnSaki).Value = wsMain.Range("G" & lnGyo).Value
        End If
        
        '残高の計算
        lnZandaka = lnZandaka + wsSaki.Range("I" & lnSaki).Value + wsSaki.Range("J" & lnSaki).Value
        wsSaki.Range("K" & lnSaki).Value = lnZandaka
        
        dt = wsMain.Range("C" & lnGyo).Value
        wsSaki.Range("B" & lnSaki).Value = Right(Year(dt), 2)
        wsSaki.Range("C" & lnSaki).Value = Month(dt)
        wsSaki.Range("D" & lnSaki).Value = Day(dt)

        lnSaki = lnSaki + 1
    Next
    
    '罫線を引く
    Keisen
End Sub

Sub Keisen()
    Dim ws As Worksheet
    Dim lnGyoMx As Long
    For Each ws In Worksheets
        Select Case ws.Name
            Case Is = "main", "main1"
            Case Else
                lnGyoMx = ws.Range("B" & ws.Rows.Count).End(xlUp).Row
                ws.Range("B16:K" & lnGyoMx).Borders.LineStyle = xlContinuous
        End Select
    Next
End Sub

Sub DeleteSheets_Fin()
    Dim ws As Worksheet
    For Each ws In Worksheets
        Select Case ws.Name
            Case Is = "main", "main1"
            Case Else
                Application.DisplayAlerts = False
                ws.Delete
                Application.DisplayAlerts = True
        End Select
    Next
End Sub


9419 : 小川慶一の回答 (2018-02-21 09:18:11)

受講生 さん:

> 私が作成したプログラムは、全てのシート作成後、別のサブプロシージャを作成して、
> for each ~ next で、全てのシートに対して罫線を引くというものです。

それでも良いかと思います。
この課題だけで考えたら、たしかにそのほうが分かりやすいですね。

僕が見本で示した以下の型もマスターしておいてください。

for
    if 切り替えのタイミングで、かつ、初回じゃなかったら
        '特定の処理
    end if
    'ありきたりな処理
next
'特定の処理


ここではあまり書きませんが、このパターンのほうがキレイにキマる仕事も多々あります。



> 小川先生
>
> お世話になっております。
> 本課題の罫線を引くロジックに関して質問があり投稿しました。
>
> 小川先生の書かれたサンプルは、シートを作成する毎に罫線を引いていますが、
> 私が作成したプログラムは、全てのシート作成後、別のサブプロシージャを作成して、
> for each ~ next で、全てのシートに対して罫線を引くというものです。
>
> プログラムの実行速度に関しては、小川先生の書かれたプログラムの方が速いと思いますが、
> プログラムの保守性や分かりやすさを考慮した場合は、罫線作成のための別のサブプロシージャを
> 作成した方が良いのかなという気もします(あくまでも個人的な所感です)。
>
> 実際の業務では、どちらの書き方が一般的なのでしょうか?


9411 : 受講生さんのコメント (2018-02-20 22:46:09)

小川先生

お世話になっております。
本課題の罫線を引くロジックに関して質問があり投稿しました。

小川先生の書かれたサンプルは、シートを作成する毎に罫線を引いていますが、
私が作成したプログラムは、全てのシート作成後、別のサブプロシージャを作成して、
for each ~ next で、全てのシートに対して罫線を引くというものです。

プログラムの実行速度に関しては、小川先生の書かれたプログラムの方が速いと思いますが、
プログラムの保守性や分かりやすさを考慮した場合は、罫線作成のための別のサブプロシージャを
作成した方が良いのかなという気もします(あくまでも個人的な所感です)。

実際の業務では、どちらの書き方が一般的なのでしょうか?


9218 : 受講生さんのコメント (2017-12-12 20:30:33)

小川先生

大変お世話になっております。
[5bai]発展編フォローセミナーNo.3~No.7のメール送付をありがとうございました。
[5bai]発展編フォローセミナーNo.2のメールをうまく受信できていませんでした。
大変お手数ですが、[5bai]発展編フォローセミナーNo.2のメールをご再送をお願いします。
大変お手数ですが、どうぞよろしくお願いいたします。


9171 : 小川慶一の回答 (2017-12-04 14:27:39)

三橋さん:

お楽しみを☆


9165 : 三橋さんのコメント (2017-12-03 16:21:22)

小川様

返信ありがとうございます。
このパターンをぜひ身につけて、いろんなところに応用したいと思います。
ありがとうございます。


9161 : 小川慶一の回答 (2017-12-02 13:29:33)

三橋さん:

以下は、パターンです。このパターンをマスターすると、できる仕事の幅が一気に広がりますよ。

ループの中で初期化→データ生成→初期化→データ生成...というくり返しをする場合:
[1] 1回目以降の「初期化」の直前で、直前のデータ生成の後処理をする
[2] ループを抜けた直後にもデータ生成の後処理をする


9158 : 三橋さんのコメント (2017-12-02 09:30:56)

罫線を入れるタイミングは、何度もステップインを繰り返してやっと理解できました。今までだったら罫線なしのシートを全部作ってから、For~Next構文で全シートを1シート毎に罫線を引く処理をしていたかもしれません。
何度も繰り返して身につけたいと思います。


2774 : 小川慶一の回答 (2014-10-22 10:34:29)

匿名 さん:

よかったです。ひきつづきよろしくお願いいたします。
※こういうところでマクロのパフォーマンスは大きく変わりますね。

>小川先生:
>
>>それではあまりよろしくない、ということはもうご理解いただけたでしょうか。
>はい、理解できました。
>小川先生がなぜあの場所でCallしたのかも、あわせて理解できました。
>
>>匿名 さん:
>>
>>お返事遅れました。
>>宿題については次回解説なので、それを見たうえで質問いただければと思います。
>>
>>> Nextの上でCallしたら、特に修正箇所もなくうまくいったように思えます。
>>
>>それではあまりよろしくない、ということはもうご理解いただけたでしょうか。
>>
>>
>>>>>ヒントは、各シートでの作業が終わるタイミングで、ということです。
>>>と書かれていたので、Nextの上でCallしたら、特に修正箇所もなくうまくいったように思えます。
>>>それでもいいでしょうか?
>>>(ついでに罫線を引く部分も、必要ない部分は削除しました)。
>>
>


2769 : 受講生さんのコメント (2014-10-21 21:37:19)

小川先生:

>それではあまりよろしくない、ということはもうご理解いただけたでしょうか。
はい、理解できました。
小川先生がなぜあの場所でCallしたのかも、あわせて理解できました。

>匿名 さん:
>
>お返事遅れました。
>宿題については次回解説なので、それを見たうえで質問いただければと思います。
>
>> Nextの上でCallしたら、特に修正箇所もなくうまくいったように思えます。
>
>それではあまりよろしくない、ということはもうご理解いただけたでしょうか。
>
>
>>>>ヒントは、各シートでの作業が終わるタイミングで、ということです。
>>と書かれていたので、Nextの上でCallしたら、特に修正箇所もなくうまくいったように思えます。
>>それでもいいでしょうか?
>>(ついでに罫線を引く部分も、必要ない部分は削除しました)。
>


2760 : 小川慶一の回答 (2014-10-21 07:51:31)

匿名 さん:

お返事遅れました。
宿題については次回解説なので、それを見たうえで質問いただければと思います。

> Nextの上でCallしたら、特に修正箇所もなくうまくいったように思えます。

それではあまりよろしくない、ということはもうご理解いただけたでしょうか。


>>>ヒントは、各シートでの作業が終わるタイミングで、ということです。
>と書かれていたので、Nextの上でCallしたら、特に修正箇所もなくうまくいったように思えます。
>それでもいいでしょうか?
>(ついでに罫線を引く部分も、必要ない部分は削除しました)。


2752 : 受講生さんのコメント (2014-10-18 16:52:22)

>>ヒントは、各シートでの作業が終わるタイミングで、ということです。
と書かれていたので、Nextの上でCallしたら、特に修正箇所もなくうまくいったように思えます。
それでもいいでしょうか?
(ついでに罫線を引く部分も、必要ない部分は削除しました)。


3291 : ガラパゴスタディー事務局の回答 (2014-05-12 11:26:00)

荏隈さん:

ハードな学びになっているようで、なによりです。

これ、実は、基礎編フォロー講座最後のほうで紹介したネタと型は同じです。

for 条件 then    if 最初じゃなかったらら then        特別な処理 '[1] 今回なら、作業対象のシートに罫線を引くこと        次の作業対象に移動する '[2] 今回なら、次のシートを作ってアクティブに        初期化すべき変数を初期化    end if    主要なパターンの処理(今回なら、作業対処のシートにデータを投入すること)end if特別な処理(今回なら、作業対象のシートに罫線を引くこと)


> しかし、真新しい技術ではなく、既存の技術を使って組み合わせていくというのはすごく良い頭のトレーニングになりますね。

まさに。
というか、「頭の使い方」と「体の使い方」がちゃっとできていれば、基本的な道具だけでかなり仕事は片づくんですよね。
マクロ書くのに、難しい知識は必要ないです。



3289 : 荏隈 直樹さんのコメント (2014-05-10 19:44:00)

今回も大変ハードでした。
とりあえず、予習の段階でのマクロ文です。

Sub yoshu6()    DeleteSheets_Fin    Dim lnFm As Long    Dim lnFmMx As Long    Dim st As String    Dim shFm As Worksheet    Dim shTo As Worksheet    Dim dt As Date '追加された行        Set shFm = Worksheets("main")    lnFmMx = shFm.Range("B65536").End(xlUp).Row        Dim lnTo As Long    Dim lnToZ As Long    Dim lnToMx As Long    For lnFm = 2 To lnFmMx        If st <> shFm.Range("B" & lnFm).Value Then            st = shFm.Range("B" & lnFm).Value            Sheets("main1").Copy After:=Sheets(2)            Set shTo = ActiveSheet            shTo.Name = st            lnTo = 16        End If                shTo.Range("H" & lnTo).Value = shFm.Range("F" & lnFm).Value        shTo.Range("E" & lnTo).Value = shFm.Range("D" & lnFm).Value        shTo.Range("F" & lnTo).Value = shFm.Range("E" & lnFm).Value        If shFm.Range("G" & lnFm).Value > 0 Then            shTo.Range("I" & lnTo).Value = shFm.Range("G" & lnFm).Value        Else            shTo.Range("J" & lnTo).Value = shFm.Range("G" & lnFm).Value        End If        dt = shFm.Range("C" & lnFm).Value        shTo.Range("B" & lnTo).Value = Right(Year(dt), 2)        shTo.Range("C" & lnTo).Value = Month(dt)        shTo.Range("D" & lnTo).Value = Day(dt)                shTo.Range("K" & lnTo).Value = shTo.Range("I" & lnTo).Value + shTo.Range("J" & lnTo).Value + shTo.Range("K" & lnTo - 1).Value        lnTo = lnTo + 1                lnToMx = shTo.Range("B65536").End(xlUp).Row        Range("B16:K" & lnToMx).Select        With Selection.Borders(xlEdgeLeft)            .LineStyle = xlContinuous            .ColorIndex = 0            .TintAndShade = 0            .Weight = xlThin        End With        With Selection.Borders(xlEdgeTop)            .LineStyle = xlContinuous            .ColorIndex = 0            .TintAndShade = 0            .Weight = xlThin        End With        With Selection.Borders(xlEdgeBottom)            .LineStyle = xlContinuous            .ColorIndex = 0            .TintAndShade = 0            .Weight = xlThin        End With        With Selection.Borders(xlEdgeRight)            .LineStyle = xlContinuous            .ColorIndex = 0            .TintAndShade = 0            .Weight = xlThin        End With        With Selection.Borders(xlInsideVertical)            .LineStyle = xlContinuous            .ColorIndex = 0            .TintAndShade = 0            .Weight = xlThin        End With        With Selection.Borders(xlInsideHorizontal)            .LineStyle = xlContinuous            .ColorIndex = 0            .TintAndShade = 0            .Weight = xlThin        End With    NextEnd Sub


実際動かしてみて、結果は要件どおりになりましたが、
罫線を掛ける処理が1行毎に行われてしまい、処理にやたら時間がかかっておりました。
これは絶対もっとスマートなやり方があると思いました。
しかし、結局思いつかず、セミナーNo7へ。

行間空けの手前まで来て、
If st <> shFm.Range("B" & lnFm).Value Then
後に入れると言うところ迄は思いついたのですが、

・2行目で「愛知製本」を見つけたときに
いきなり罫線を引く作業を実行してしまう
・最後に追加されたシートで罫線を引く作業が実施されない

この2点の解決方法が思いつきませんでした。

しかし、真新しい技術ではなく、既存の技術を使って組み合わせていくというのはすごく良い頭のトレーニングになりますね。


3266 : ガラパゴスタディー事務局の回答 (2013-09-26 23:46:00)

やまださん:

さすがです!

> 一取引ごとに罫線を引くので、取引の数だけ罫線を引くことになるのが処理を多くしてしまい

ですね。1回だけでよいわけです。

> 深刻な影響が出るとき

やださんのやり方だと、取引先の数が同じでも、取引数が変わるとパフォーマンスに大きな影響が出ます。

以下の2つで比較してみましょう。

[a] 取引先数20件、取引数300件のとき
[b] 取引先数20件、取引数30000件のとき

見本のやり方だと、罫線を引く作業をするのはどちらの場合も20回です。
やまださんのやり方だと、[a]のときは300回ですが、[b]のときには30000回にふくれあがります。

300回でもすでに多いですが(汗

> Macro2_1 のある行にブレークポイント入れるとよいかも。

パフォーマンスの差を生む要因となっていると思われるところに十分な注意を払うことが肝心です。
そういう意味でブレークポイントを入れてテストしてもらいました。


3265 : やまださんのコメント (2013-09-26 21:08:00)

小川先生。ブレークポイントを入れて考えてみました。

一取引ごとに罫線を引くので、取引の数だけ罫線を引くことになるのが処理を多くしてしまい、時間がかかる原因だと思いました(他方、小川先生のコードの場合、一シートごとに罫線を引くのでシートの数だけ罫線を引くから私のコードより処理量が少なくてすむ)

>深刻な影響が出るとき
取引の数が多いとき、処理が膨大な量になってなかなか終了しないのが問題ではないでしょうか。いま316取引でマクロを実行したところ、32秒かかりました。これがもし100倍の31600取引になると3200秒(53分)かかってしまう?(概算ですが)


3264 : ガラパゴスタディー事務局の回答 (2013-09-24 23:11:00)

やまださん:

がんばっていますね。

> ちょっと通常より時間がかかるけど何となくいけているような気がするんですが・・

どうしていけてないか考えてみて。
Macro2_1 のある行にブレークポイント入れるとよいかも。

どうしていけてないか考えて結論がでたら、その問題がもっと深刻な影響につながるとしたらどういうデータのときかを考えてみてください。


3263 : やまださんのコメント (2013-09-24 22:30:00)

罫線のためのマクロを下記のように配置(下から3行目のみ)にしてみたんですがこれでも構いませんでしょうか?ちょっと通常より時間がかかるけど何となくいけているような気がするんですが・・

Sub EnterValues5_yamada()    DeleteSheets_Fin    Dim lnFm As Long    Dim lnFmMx As Long    Dim st As String    Dim shFm As Worksheet    Dim shTo As Worksheet    Dim dt As Date '追加された行    Set shFm = Worksheets("main")    lnFmMx = shFm.Range("B65536").End(xlUp).Row        Dim lnTo As Long    For lnFm = 2 To lnFmMx        If st <> shFm.Range("B" & lnFm).Value Then            st = shFm.Range("B" & lnFm).Value            Sheets("main1").Copy After:=Sheets(2)            Set shTo = ActiveSheet            shTo.Name = st            lnTo = 16        End If                  shTo.Range("H" & lnTo).Value = shFm.Range("F" & lnFm).Value        shTo.Range("E" & lnTo).Value = shFm.Range("D" & lnFm).Value        shTo.Range("F" & lnTo).Value = shFm.Range("E" & lnFm).Value        If shFm.Range("G" & lnFm).Value > 0 Then            shTo.Range("I" & lnTo).Value = shFm.Range("G" & lnFm).Value        Else            shTo.Range("J" & lnTo).Value = shFm.Range("G" & lnFm).Value        End If        If lnTo = 16 Then        shTo.Range("K" & lnTo).Value = shFm.Range("G" & lnFm).Value        Else        shTo.Range("k" & lnTo).Value = shFm.Range("G" & lnFm).Value + shTo.Range("k" & lnTo).Offset(-1).Value        End If                dt = shFm.Range("C" & lnFm).Value        shTo.Range("B" & lnTo).Value = Right(Year(dt), 2)        shTo.Range("C" & lnTo).Value = Month(dt)        shTo.Range("D" & lnTo).Value = Day(dt)                lnTo = lnTo + 1                Macro2_1 'ここに配置    NextEnd Sub


3227 : ガラパゴスタディー事務局の回答 (2013-08-01 10:50:00)

望月さん:

おはようございます。

資料等、活用いただけているようでとてもうれしいです。あのマインドマップは、僕の頭の中にあるエクセルVBA像をそのまま落とし込んだ資料です。
マクロを活用していけばいくほど、その中からまたいろいろなものを引き出せるようになるかと思います。吸収できるものは何でも吸収してください。ひきつづき、よろしくお願いいたします ヾ(´ー`)ノ


3226 : 望月 晋一さんのコメント (2013-08-01 10:28:00)

小川先生、早速添削して下さいましてありがとうございます。ご指摘いただいた箇所は、今後の課題実習で生かします。セミナー後にこうしたフォロー指導をしていただけると、より身が入ります。なお、私はふだんセミナーの時に使ったマインドマップの教材をよく見返しています。学んだ事を頭に刻み付けるうえで、とても見やすく吸収しやすいレジュメだと思います。よくある箇条書きにはない、インパクトの強さも感じます。こうした資料からも学び方を得られると気が付きました。


3225 : ガラパゴスタディー事務局の回答 (2013-08-01 08:30:00)

望月さん:

問題点、何もないです。とてもキレイで、よいお手本です。

あえて、改善点を示すとすれば...。↓てとこかな。ホント、あえて書くなら、というところですが。

[1] right関数とyear関数を組み合わせているところは、format関数で表現するのもあり。
[2] with wsD ... end with で表現するとちょっとキレイかな、と思うところもちょっとあり。
[3] 同様に、 with wsD.Range("B16:K" & nKisai) ... end with で表記してみたいところも。
[4] [2], [3] の複合形で、 with wsD ... end with の中に、 with .Range("B16:K" & nKisai) ... end with って書くのもあり。


3224 : 望月 晋一さんのコメント (2013-07-31 20:34:00)

作成してみたプログラムを見て、問題点をご指摘いただければ幸いです。

Sub denpyosakusei()    Dim ws As Worksheet    Dim wsM As Worksheet    Dim wsD As Worksheet    Dim nGyo As Long    Dim nSaigo As Long    Dim stTm As String    Dim nKisai As Long    Dim nKin As Long        Application.DisplayAlerts = False    For Each ws In Worksheets        If ws.Name <> "main" And ws.Name <> "main1" Then            ws.Delete        End If    Next    Application.DisplayAlerts = True        Set wsM = Worksheets("main")    nSaigo = wsM.Range("B" & Rows.Count).End(xlUp).Row        For nGyo = 2 To nSaigo        If stTm <> wsM.Range("B" & nGyo).Value Then            Worksheets("main1").Copy after:=Worksheets(2)            Set wsD = ActiveSheet            stTm = wsM.Range("B" & nGyo).Value            wsD.Name = stTm            nKisai = 16        End If            wsD.Range("E" & nKisai).Value = wsM.Range("D" & nGyo).Value        wsD.Range("F" & nKisai).Value = wsM.Range("E" & nGyo).Value        wsD.Range("H" & nKisai).Value = wsM.Range("F" & nGyo).Value        wsD.Range("B" & nKisai).Value = Right(Year(wsM.Range("C" & nGyo).Value), 2)        wsD.Range("C" & nKisai).Value = Month(wsM.Range("C" & nGyo).Value)        wsD.Range("D" & nKisai).Value = Day(wsM.Range("C" & nGyo).Value)        nKin = wsM.Range("G" & nGyo).Value        If nKin > 0 Then            wsD.Range("I" & nKisai).Value = nKin        Else            wsD.Range("J" & nKisai).Value = nKin        End If        If nKisai = 16 Then            wsD.Range("K16").Value = nKin        Else            wsD.Range("K" & nKisai).Value = wsD.Range("K" & nKisai - 1).Value _                + wsD.Range("I" & nKisai).Value + wsD.Range("J" & nKisai).Value        End If                If stTm <> wsM.Range("B" & nGyo + 1).Value Then            wsD.Range("B16:K" & nKisai).Borders(xlEdgeLeft).LineStyle = xlContinuous            wsD.Range("B16:K" & nKisai).Borders(xlEdgeTop).LineStyle = xlContinuous            wsD.Range("B16:K" & nKisai).Borders(xlEdgeBottom).LineStyle = xlContinuous            wsD.Range("B16:K" & nKisai).Borders(xlEdgeRight).LineStyle = xlContinuous            wsD.Range("B16:K" & nKisai).Borders(xlInsideVertical).LineStyle = xlContinuous            wsD.Range("B16:K" & nKisai).Borders(xlInsideHorizontal).LineStyle = xlContinuous        End If                nKisai = nKisai + 1        Next    End Sub


3188 : ガラパゴスタディー事務局の回答 (2013-04-08 10:10:00)

深田さん:

shTo.Range("K" & lnto).Value = "=SUM(RC[-2]:RC[-1])"


↑値を直接記入することとの比較になりますが、エクセルシートの中に関数が残ることへの評価次第ですね。
(どちらもありと言えばありかと思います)


> オフセットについては全く考えていませんでしたが、オフセットの方が良かったのでしょうか?

んなことないですよ。これも、どちらもありです。


> 罫線の引き方についてはマクロの自動記録まではできましたが、組み込み方がうまくいかずに苦労しましたが、ようやく理解できました。

ポイントは、 For Next 構文の最初と終わりには特殊な処理が入りがちだ、ということです。
今回であれば、入った直後と、出た直後ですね。


3186 : 深田豊さんのコメント (2013-04-07 11:44:00)

残高入力では貸方・借方の合計かと考えて、以下のように作ってみました。

            If shFm.Range("G" & lnFm).Value > 0 Then                shTo.Range("I" & lnto).Value = shFm.Range("G" & lnFm).Value            Else                shTo.Range("J" & lnto).Value = shFm.Range("G" & lnFm).Value            End If            shTo.Range("K" & lnto).Value = "=SUM(RC[-2]:RC[-1])"            dt = shFm.Range("C" & lnFm).Value            shTo.Range("B" & lnto).Value = Right(Year(dt), 2)            shTo.Range("C" & lnto).Value = Month(dt)            shTo.Range("D" & lnto).Value = Day(dt)

オフセットについては全く考えていませんでしたが、オフセットの方が良かったのでしょうか?


罫線の引き方についてはマクロの自動記録まではできましたが、組み込み方がうまくいかずに苦労しましたが、ようやく理解できました。


3133 : ガラパゴスタディー事務局の回答 (2013-02-06 08:53:00)

大椛さん:

あー、すいません。そうでした。
(僕が出題者なのに、、(汗 )

いただいたマクロ。キモはここ↓ですね。

[1] 上のと違ったら罫線とする
[2] ただし、初回はスキップ
[3] For Nextのくり返し範囲を、データ数+1までとする
[3] For Nextの最後では、罫線だけ引いてさっさと撤退 (Exit For)

おもしろいアルゴリズムだと思います。
僕の代わりに先生やってもらいたいくらい。(ガチに)

お手本と、どちらのほうがよいか善悪不明ですね。
あえて言うなら、以下の条件判断がループの回数だけ発生してしまうので、それを工数が多いとみるかどうか。

If lnFm = lnFmMx Then    Exit ForEnd If


大量データを用意して計測してみないとどちらのほうがパフォーマンスが高いかは判断できないかとも思います。


3132 : 大椛輝志さんのコメント (2013-02-06 07:33:00)

小川様

問題7ですが、mainシートの得意先がソートされていないためだと思います。
(たしか、問題8がソートを扱ってましたよね)
問題6のファイルではきちんと動いたのに、問題7では動かなかったため、気が付きました。


3131 : ガラパゴスタディー事務局の回答 (2013-02-06 07:02:00)

大椛さん:

僕の環境で動かしてみたら、

lnFm = 11 のとき、

shTo.Name = st

のところで止まりました。すでに同名のシートがある、という趣旨のエラーメッセージ。

大椛さんのところでは問題なく動きましたか?


3130 : 大椛輝志さんのコメント (2013-02-05 23:45:00)

罫線を引くマクロを別に書いておいて、必要なところに呼び出せば良かったんですね。。。確かに、シートを消すマクロでそうしてました。
前回の予習作成では、それが浮かばず、マクロが長くならないようにしようとして、逆に長くなってしまいました。
(調べるデータの行を+1したり、Exit Forを使ったり)
長いですが、コメントいただければ幸いです。

code
Sub Syukudai_EnterValues4()
DeleteSheets_Fin
Dim lnFm As Long
Dim lnFmMx As Long
Dim st As String
Dim shFm As Worksheet
Dim shTo As Worksheet
Dim dt As Date
Dim zan As Long
Set shFm = Worksheets("main")
lnFmMx = shFm.Range("B65536").End(xlUp).Row + 1

Dim lnTo As Long
For lnFm = 2 To lnFmMx
If st <> shFm.Range("B" & lnFm).Value Then
If lnFm > 2 Then

With shTo.Range("B16:K" & lnTo).Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With shTo.Range("B16:K" & lnTo).Borders(xlEdgeTop)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With shTo.Range("B16:K" & lnTo).Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With shTo.Range("B16:K" & lnTo).Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With shTo.Range("B16:K" & lnTo).Borders(xlInsideVertical)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With shTo.Range("B16:K" & lnTo).Borders(xlInsideHorizontal)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
End If

If lnFm = lnFmMx Then
Exit For
End If

st = shFm.Range("B" & lnFm).Value
Sheets("main1").Copy After:=Sheets(2)
Set shTo = ActiveSheet
shTo.Name = st
lnTo = 16
zan = 0
End If

If lnFm = lnFmMx Then
Exit For
End If

shTo.Range("H" & lnTo).Value = shFm.Range("F" & lnFm).Value
shTo.Range("E" & lnTo).Value = shFm.Range("D" & lnFm).Value
shTo.Range("F" & lnTo).Value = shFm.Range("E" & lnFm).Value

If shFm.Range("G" & lnFm).Value > 0 Then
shTo.Range("I" & lnTo).Value = shFm.Range("G" & lnFm).Value
Else
shTo.Range("J" & lnTo).Value = shFm.Range("G" & lnFm).Value
End If

zan = zan + shTo.Range("I" & lnTo).Value + shTo.Range("J" & lnTo).Value
shTo.Range("K" & lnTo).Value = zan

dt = shFm.Range("C" & lnFm).Value
shTo.Range("B" & lnTo).Value = Right(Year(dt), 2)
shTo.Range("C" & lnTo).Value = Month(dt)
shTo.Range("D" & lnTo).Value = Day(dt)

lnTo = lnTo + 1
Next
End Sub
/code


3120 : ガラパゴスタディー事務局の回答 (2013-01-29 16:37:00)

山根さん:

> 先生によく書けていると言われると安心します。


ともあれ、実際に成果を感じていらっしゃいますし、特に問題ないかと。
よく書けていますよ。

一時的に他人基準になりがちなのは、仕方ないかと思います。


> やりたいことを実現する方法はいくつかあるのはわかってても

TPOに無関係に不変な正解があると考えるとハマります。
基礎編でお伝えしたとおり、プログラミングとは、手順書作成です。

日本語で書く手順書であれば、正解はひとつとは限らないですよね。それと同じです。



3119 : 山根信行さんのコメント (2013-01-29 07:58:00)

罫線は少し試してみます。

自信をなくすというか不安になるんですよね。
やりたいことを実現する方法はいくつかあるのはわかっててもこの選択肢で良かったかどうか。
特に記述が長くなったり読みにくくなったりが要因ですね。
ポジティブな面でいえばマクロを書くのが以前よりずっと楽しいですね。結果が出るのも速くなりましたし。

先生によく書けていると言われると安心します。


3118 : ガラパゴスタディー事務局の回答 (2013-01-29 05:19:00)

山根さん:

Offsetでなくてもよいですよ。
というか、よく書けていると思います。

罫線を引くコードを入れる箇所。
これでも最終形としてはよさげですが、データの数だけ罫線を引く作業をすることになってしまいます。
本当は、追加したシートの数だけにとどめたい。さて、ではどうするか、ということです。


それにしても、書き進められているのに自信をなくすとは...。とても不思議。
セミナーを受ける前と比べて、ポジティブな変化としてどんなことがありましたか。そっちにもっとフォーカスしてみたい気も (^^;


3117 : 山根信行さんのコメント (2013-01-29 00:22:00)

残高のところでOffsetが登場するとは思いもしませんでした。私はこうかなぁとなんとなく書いたらうまくいったっぽいです。記述が長くなってしまったのは気持ち悪いですが。
うーん、なんか間違ってる気がします。


どのような罫線でもいいとあったので覚えていた一番簡単な罫線を引きましたが、コードを記述する場所が違います。
これも問題ありなんですかね。

書き進めるたびに自信なくなります。
今回も苦労しました。

Sub hatten()    Dim cnt As Long    Dim ssg As Long    Dim ListName As String    Dim wsData As Worksheet    Dim wsFormat As Worksheet    Dim tky As Long    Dim RcDay As Date        Call wsDLT        Set wsData = Worksheets("main")    Set wsFormat = Worksheets("main1")    ssg = wsData.Range("B65536").End(xlUp).Row    For cnt = 2 To ssg            ListName = wsData.Range("B" & cnt).Value        If wsData.Range("B" & cnt).Value <> wsData.Range("B" & cnt - 1).Value Then            wsFormat.Copy AFTER:=wsData            Worksheets(3).Name = ListName        End If            tky = Worksheets(ListName).Range("H65536").End(xlUp).Row + 1        With Worksheets(ListName)            .Range("H" & tky).Value = wsData.Range("F" & cnt).Value            .Range("E" & tky).Value = wsData.Range("D" & cnt).Value            .Range("F" & tky).Value = wsData.Range("E" & cnt).Value        If wsData.Range("G" & cnt).Value > 0 Then            .Range("I" & tky).Value = wsData.Range("G" & cnt).Value        Else            .Range("J" & tky).Value = wsData.Range("G" & cnt).Value        End If            RcDay = wsData.Range("C" & cnt).Value            .Range("B" & tky).NumberFormatLocal = "@"            .Range("B" & tky).Value = Right(Year(RcDay), 2)            .Range("C" & tky).Value = Month(RcDay)            .Range("D" & tky).Value = Day(RcDay)            .Range("k" & tky).Value = .Range("I" & tky).Value + .Range("J" & tky).Value + .Range("K" & tky - 1).Value            .Range("B" & tky, "K" & tky).Borders.LineStyle = True                    End With                NextEnd SubSub wsDLT()    Dim WS As Worksheet    Application.DisplayAlerts = False    For Each WS In Worksheets        If Left(WS.Name, 4) <> "main" Then            WS.Delete        End If    Next    Application.DisplayAlerts = True    End Sub


3103 : ガラパゴスタディー事務局の回答 (2013-01-21 19:00:00)

佐藤さん:

くり返し作業の最初と最後だけ特別な処理がある、というのは、よくあるパターンです。

リアルの仕事で言えば、例えば、異動してきたばかりのスタッフさんは、総務の人からロッカーの使い方とかについてレクチャーを受けて、いろいろな人に「はじめまして」のご挨拶をして仕事を開始します。
二日目以降は通常通りに仕事をしますが、辞めるか別の部署に異動になるかする最終日には、やはり総務の人のお世話になったり、いろいろな人に「お世話になりました」のご挨拶をしたりします。
それと同じ感覚。


3101 : 佐藤 尚子さんのコメント (2013-01-19 07:22:00)

罫線はやっぱりなかなか正しく引けませんでした。最初はどのシートも最初のシートと同じ範囲を指定してしまっていました。(自動記録した際の余計な1行を削除していなかったのが原因でした。)
構文の挿入先は答えを見て何度かステップインで動かした後、やっと「へー」となりました。「各シートでの作業が終わるタイミング」とはここなんですね。最初はどうしてシート"main"にも罫線がひかれるのか、答えを見てもわかりませんでしたが、それもステップインで何度か見てやっとわかりました。
繰り返し学習したいと思います。
ありがとうございました。


3100 : ガラパゴスタディー事務局の回答 (2013-01-14 08:24:00)

竹端さん:

罫線の件。ご失敗、おめでとうございます ヾ(´ー`)ノ
そういう経験が、学びを深くしてくれます。

offsetは、使用方法というより、概念を先に意識してください。

起点になるセルを決めて、そこからの相対位置で別のセルを表現しよう、ということです。

ちなみに、webページ(ブログ記事とかでも)でよく

10件だけ表示されていて、「次へ」ボタンをクリックすると、もう10件表示されたりするでしょ。

ああいうのも、 .offset ですよ。

その場合は、データベースにアクセスして得られた10件とかのデータを、 .offsetで範囲指定して、その範囲のものを一気に表示しているんです。

Gmailなんかもしかり。


VBAで見ていることが、自分が普段触れているIT技術のどこでも同じように活用されているだろうか、という、そういう視点で日常を送ってください。
そうすると、より学びが深く(文字通り!)なると思います。


3099 : 竹端博希さんのコメント (2013-01-13 14:57:00)

Offsetの使用方法については、すっかり忘れておりましたので、改めてテキストを見て思い出した次第です。何度も使わないと身に付かないですね・・・

罫線は自動記録を利用すればスンナリとできましたし、罫線の範囲だけを変えてあげれば、それほどの苦でもなかったです。構文の挿入先も何度か自分なりに試してみて、答えに辿り着きました。(最初は、一番最初のシートしか罫線が施されていませんでしたが・・・)


3日がかりのその仕事、3分で終わらせる方法教えます。ガラパゴスタディーオンライン講座 ユーザー登録

本講座の動画一覧

  1. 【動画1】 発展編1 フォローメールセミナー 第1回
    【動画1】 発展編1 フォローメールセミナー 第1回 未習得
  2. 【動画2】 発展編1 フォローメールセミナー 第2回
    【動画2】 発展編1 フォローメールセミナー 第2回 未習得
  3. 【動画3】 発展編1 フォローメールセミナー 第3回
    【動画3】 発展編1 フォローメールセミナー 第3回 未習得
  4. 【動画4】 発展編1 フォローメールセミナー 第4回
    【動画4】 発展編1 フォローメールセミナー 第4回 未習得
  5. 【動画5】 発展編1 フォローメールセミナー 第5回
    【動画5】 発展編1 フォローメールセミナー 第5回 未習得
  6. 【動画6】 発展編1 フォローメールセミナー 第6回
    【動画6】 発展編1 フォローメールセミナー 第6回 未習得
  7. 【動画7】 発展編1 フォローメールセミナー 第7回
    【動画7】 発展編1 フォローメールセミナー 第7回 未習得
  8. 【動画8】 発展編1 フォローメールセミナー 第8回
    【動画8】 発展編1 フォローメールセミナー 第8回 未習得
  9. 【動画9】 発展編1 フォローメールセミナー 第9回
    【動画9】 発展編1 フォローメールセミナー 第9回 未習得
  10. 【動画10】 発展編1 フォローメールセミナー 第10回
    【動画10】 発展編1 フォローメールセミナー 第10回 未習得
  11. 【動画11】 午後のフォローアップ No.1
    【動画11】 午後のフォローアップ No.1 未習得
  12. 【動画12】 発展編1 フォローメールセミナー 第11回
    【動画12】 発展編1 フォローメールセミナー 第11回 未習得
  13. 【動画13】 午後のフォローアップ No.2
    【動画13】 午後のフォローアップ No.2 未習得
  14. 【動画14】 発展編1 フォローメールセミナー 第12回
    【動画14】 発展編1 フォローメールセミナー 第12回 未習得
  15. 【動画15】 午後のフォローアップ No.3
    【動画15】 午後のフォローアップ No.3 未習得
  16. 【動画16】 発展編1 フォローメールセミナー 第13回
    【動画16】 発展編1 フォローメールセミナー 第13回 未習得
  17. 【動画17】 午後のフォローアップ No.4
    【動画17】 午後のフォローアップ No.4 未習得
  18. 【動画18】 発展編1 フォローメールセミナー 第14回
    【動画18】 発展編1 フォローメールセミナー 第14回 未習得
  19. 【動画19】 午後のフォローアップ No.5
    【動画19】 午後のフォローアップ No.5 未習得
  20. 【動画20】 発展編1 フォローメールセミナー 第15回
    【動画20】 発展編1 フォローメールセミナー 第15回 未習得
  21. 【動画21】 午後のフォローアップ No.6
    【動画21】 午後のフォローアップ No.6 未習得
  22. 【動画22】 発展編1 フォローメールセミナー 第16回
    【動画22】 発展編1 フォローメールセミナー 第16回 未習得
  23. 【動画23】 午後のフォローアップ No.7
    【動画23】 午後のフォローアップ No.7 未習得
  24. 【動画24】 発展編1 フォローメールセミナー 第17回
    【動画24】 発展編1 フォローメールセミナー 第17回 未習得
  25. 【動画25】 午後のフォローアップ No.8
    【動画25】 午後のフォローアップ No.8 未習得
  26. 【動画26】 発展編1 フォローメールセミナー 第18回
    【動画26】 発展編1 フォローメールセミナー 第18回 未習得
  27. 【動画27】 午後のフォローアップ No.9
    【動画27】 午後のフォローアップ No.9 未習得
  28. 【動画28】 発展編1 フォローメールセミナー 第19回
    【動画28】 発展編1 フォローメールセミナー 第19回 未習得
  29. 【動画29】 午後のフォローアップ No.10
    【動画29】 午後のフォローアップ No.10 未習得
  30. 【動画30】 発展編1 フォローメールセミナー 第20回
    【動画30】 発展編1 フォローメールセミナー 第20回 未習得
  31. 【動画31】 午後のフォローアップ No.11
    【動画31】 午後のフォローアップ No.11 未習得
  32. 【動画32】 発展編1 フォローメールセミナー 第21回
    【動画32】 発展編1 フォローメールセミナー 第21回 未習得
  33. 【動画33】 午後のフォローアップ No.12
    【動画33】 午後のフォローアップ No.12 未習得
  34. 【動画34】 発展編1 フォローメールセミナー 第22回
    【動画34】 発展編1 フォローメールセミナー 第22回 未習得
  35. 【動画35】 午後のフォローアップ No.13
    【動画35】 午後のフォローアップ No.13 未習得
  36. 【動画36】 発展編1 フォローメールセミナー 第23回
    【動画36】 発展編1 フォローメールセミナー 第23回 未習得
  37. 【動画37】 午後のフォローアップ No.14
    【動画37】 午後のフォローアップ No.14 未習得
  38. 【動画38】 発展編1 フォローメールセミナー 第24回
    【動画38】 発展編1 フォローメールセミナー 第24回 未習得
  39. 【動画39】 午後のフォローアップ No.15
    【動画39】 午後のフォローアップ No.15 未習得
  40. 【動画40】 発展編1 フォローメールセミナー 第25回
    【動画40】 発展編1 フォローメールセミナー 第25回 未習得
  41. 【動画41】 午後のフォローアップ No.16
    【動画41】 午後のフォローアップ No.16 未習得
  42. 【動画42】 発展編1 フォローメールセミナー 第26回
    【動画42】 発展編1 フォローメールセミナー 第26回 未習得
  43. 【動画43】 午後のフォローアップ No.17
    【動画43】 午後のフォローアップ No.17 未習得
  44. 【動画44】 発展編1 フォローメールセミナー 第27回
    【動画44】 発展編1 フォローメールセミナー 第27回 未習得
  45. 【動画45】 午後のフォローアップ No.18
    【動画45】 午後のフォローアップ No.18 未習得
  46. 【動画46】 発展編1 フォローメールセミナー 第28回
    【動画46】 発展編1 フォローメールセミナー 第28回 未習得
  47. 【動画47】 午後のフォローアップ No.19
    【動画47】 午後のフォローアップ No.19 未習得
  48. 【動画48】 発展編1 フォローメールセミナー 第29回
    【動画48】 発展編1 フォローメールセミナー 第29回 未習得
  49. 【動画49】 午後のフォローアップ No.20
    【動画49】 午後のフォローアップ No.20 未習得
  50. 【動画50】 発展編1 フォローメールセミナー 第30回
    【動画50】 発展編1 フォローメールセミナー 第30回 未習得
  51. 【動画51】 午後のフォローアップ 最終回
    【動画51】 午後のフォローアップ 最終回 未習得

塾長 小川慶一

メニュー

コメント紹介

もっと見る

ページの先頭へ