オンライン講座 質問と回答

無料・有料のオンライン講座で 寄せられたメッセージの一部を紹介致します。

[8984]連想配列_3

2017-10-02 23:16:04 受講生さんからの投稿です。

発展編1のファイル"Enshu21200.xls"の伝票作成の問題で、模範解答でなく、連想配列を使って、コードを書いてみました。動きましたが、採点をしていただければ、嬉しいです。

Option Explicit
Sub CreateDenpyo()
    DeleteSheets
    CreateDenpyoExe
End Sub

Sub DeleteSheets()
    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

Sub CreateDenpyoExe()
'連想配列を使って、伝票作成のコードを書きました。
    
    Dim dic As New Scripting.Dictionary 'index=取引先名称、Item=転記先シートでの行数とする連想配列。
    Dim c As Long                       'Worksheets("main")の行数カウンター
    Dim cMx As Long                     'Worksheets("main")の最終行数
    Dim dt As Long                      'Worksheets("main")C列の日付
    Dim st As String                    'Worksheets("main")B列の取引先名称
    Dim w As Worksheet                  'Worksheets("main")のニックネーム
    
    Set w = Worksheets("main")
    cMx = w.Range("a65536").End(xlUp).Row
    
    For c = 2 To cMx
        st = w.Range("B" & c).Value
        If dic.Exists(st) = True Then
            dic.Item(st) = dic.Item(st) + 1
        Else
            dic.Add st, 16
            CreateSheets st
        End If
        
        InputData st, c, dic.Item(st)
    Next
    
    Dim vkey As Variant
    vkey = dic.Keys
    For c = LBound(vkey) To UBound(vkey)
        If Left(vkey(c), 4) <> "main" Then
            Keisen vkey(c), dic.Item(vkey(c))
        End If
    Next
    w.Select
    Range("a1").Select
End Sub

Sub CreateSheets(st As String)
    Worksheets("main1").Copy after:=Worksheets(Worksheets.Count)
    ActiveSheet.Name = st
End Sub

Sub InputData(st As String, cFm As Long, cTo As Long)
    Dim dt As Date
    Dim wTo As Worksheet
    Dim wFm As Worksheet
    Dim cKingaku
    Set wTo = Worksheets(st)
    Set wFm = Worksheets("main")
    
    dt = wFm.Range("c" & cFm).Value
    wTo.Range("b" & cTo).Value = Right(Year(dt), 2)
    wTo.Range("c" & cTo).Value = Month(dt)
    wTo.Range("d" & cTo).Value = Day(dt)
    wTo.Range("e" & cTo).Value = wFm.Range("d" & cFm).Value
    wTo.Range("f" & cTo).Value = wFm.Range("e" & cFm).Value
    wTo.Range("h" & cTo).Value = wFm.Range("f" & cFm).Value
    
    cKingaku = wFm.Range("g" & cFm).Value
    If cKingaku >= 0 Then
        wTo.Range("i" & cTo).Value = cKingaku
    Else
        wTo.Range("j" & cTo).Value = cKingaku
    End If
    
    If cTo = 16 Then
        wTo.Range("k" & cTo).Value = cKingaku
    Else
        wTo.Range("k" & cTo).Value = wTo.Range("k" & cTo - 1).Value + cKingaku
    End If

End Sub

Sub Keisen(st As Variant, c As Long)
'
' 罫線を引く
    Worksheets(st).Select
    With Range("B16:K" & c + 1)
        .Borders(xlDiagonalDown).LineStyle = xlNone
        .Borders(xlDiagonalUp).LineStyle = xlNone
        With .Borders(xlEdgeLeft)
            .LineStyle = xlContinuous
            .ColorIndex = 0
            .TintAndShade = 0
            .Weight = xlThin
        End With
        With .Borders(xlEdgeTop)
            .LineStyle = xlContinuous
            .ColorIndex = 0
            .TintAndShade = 0
            .Weight = xlThin
        End With
        With .Borders(xlEdgeBottom)
            .LineStyle = xlContinuous
            .ColorIndex = 0
            .TintAndShade = 0
            .Weight = xlThin
        End With
        With .Borders(xlEdgeRight)
            .LineStyle = xlContinuous
            .ColorIndex = 0
            .TintAndShade = 0
            .Weight = xlThin
        End With
        With .Borders(xlInsideVertical)
            .LineStyle = xlContinuous
            .ColorIndex = 0
            .TintAndShade = 0
            .Weight = xlThin
        End With
        With .Borders(xlInsideHorizontal)
            .LineStyle = xlContinuous
            .ColorIndex = 0
            .TintAndShade = 0
            .Weight = xlThin
        End With
    End With
    
End Sub

[ 続きを読む ]  返信件数:2件  [ 動画を見る] 

[8347]式と戻り値_1

2017-06-12 20:00:00 受講生さんからの投稿です。

ダウンロードしたフォルダ内のA-0、A-1、A-2の違いが分かりません。とりあえずA-0を使用していればいいのでしょうか。

[ 続きを読む ]  返信件数:1件  [ 動画を見る] 

[8309]式と戻り値_1

2017-06-07 21:44:02 受講生さんからの投稿です。

お世話になっております。
siryoフォルダ内にA-0、A-1、A-2とあり、同名フォルダや同名ファイルがある場合は、どれを使用すればいいのでしょうか。

[ 続きを読む ]  返信件数:1件  [ 動画を見る] 

[8116]引数として配列を受け取るFunctionプロシージャ

2017-05-12 18:06:44 受講生さんからの投稿です。

8114→納得。スッキリしました。ありがとうございます。

[ 続きを読む ]  返信件数:1件  [ 動画を見る] 

[8111]引数として配列を受け取るFunctionプロシージャ

2017-05-11 23:29:14 受講生さんからの投稿です。

よろしくお願いします。

Chap 04-23

Option Explicit

Sub SetCampaignFlag()
    Dim stKonyuList() As String
    Dim c As Long
    For c = 2 To Range("F65536").End(xlUp).Row
        ReDim Preserve stKonyuList(c - 2)
        stKonyuList(c - 2) = Range("F" & c).Value
    Next
    
    For c = 2 To Range("B65536").End(xlUp).Row
        '以下のIf文の中で、関数からの戻り値を利用している


        '↓のif文がなぜ成り立つのかがピンときません。
  ’Functionプロシージャ戻り値がFalseかTrueならば
  ’ If IsExists(Range("B" & c).Value, stKonyuList) =False Then
       'と書きたくなります。考え方を教えてください。
  ’よろしくお願いします。


        If IsExists(Range("B" & c).Value, stKonyuList) Then
            Range("C" & c).Value = "○"
        Else
            Range("C" & c).ClearContents
        End If
    Next
End Sub
Function IsExists(s As String, ary() As String) As Boolean
    Dim c As Long
    Dim B As Boolean
    B = False
    For c = LBound(ary) To UBound(ary)
        If s = ary(c) Then
            B = True
            Exit For
        End If
    Next
    IsExists = B

    
End Function


[ 続きを読む ]  返信件数:1件  [ 動画を見る] 

[8088]引数として配列を受け取るFunctionプロシージャ

2017-05-07 21:46:10 受講生さんからの投稿です。

SetCampaignFlagのIF文のところで理解に苦しむ。
FunctionプロシージャでBooleanでFalseかTrueとした後

If IsExists(Range("B" & c).Value, stKonyuList)  = False Then
end if

としたくなります。確り怒られますが…
もうすでに戻り値が出ているからと考えればよいのでしょうか?
初歩的な質問で恥ずかしいのですが考え方のヒントが欲しいです。
よろしくお願いします。

[ 続きを読む ]  返信件数:1件  [ 動画を見る] 

[7883] 配列操作の便利関数、オプション、その他

2017-03-31 11:15:42 平吹 敦史さんからの投稿です。

お世話様です。

テキストP41、Chap02-61のEraseステートメントの下記例題ですが、
Erase stAryの一文があってもなくても結果は一緒でした。
ステップインで追いかけましたが、いまいちわかりませんでした。

どうも、stAry(cAry)のcAry=0で例えば渋谷区の配列の中身が世田谷区の中身に上書きされた時点で、
それ以降の配列はクリアになるようでした。

なので、あえてErase stAryの一文が必要なのでしょうか?

最初は、前の配列がそのまま残っているので、クリアにしないと不要な配列が書き出されてしまうイメージでした。データ数が一緒なら上書きされて問題ないが、データ数が少ないと不要なデータが書き出されてしまうイメージです。

ですが、結果が違ったので???状態です。

ご教授願います。

Option Explicit
Dim stTgt As String '検索対象の区
Dim stAry() As String '配列
Dim cTo As Long 'データ書き出し先の行
Sub ListUpBukken()
Columns("I:J").ClearContents

cTo = 2

stTgt = "渋谷区"
ExeKensaku

stTgt = "世田谷区"
ExeKensaku

stTgt = "目黒区"
ExeKensaku

stTgt = "港区"
ExeKensaku

stTgt = "品川区"
ExeKensaku

End Sub
Sub ExeKensaku()
Dim cFm As Long '元データ表でForNext構文が使う変数
Dim cMx As Long '元データ表の最大行
Dim cAry As Long '配列のインデックス用

cMx = Range("A65536").End(xlUp).Row

cAry = 0
Erase stAry・・・・・・これをとっても結果は同じなる?
For cFm = 2 To cMx
If Range("C" & cFm).Value = stTgt Then
ReDim Preserve stAry(cAry)
stAry(cAry) = Range("F" & cFm).Value
cAry = cAry + 1
End If
Next

Range("I" & cTo).Value = stTgt & "の物件は " & UBound(stAry) + 1 & "件ヒットしました!"
cTo = cTo + 1

For cFm = LBound(stAry) To UBound(stAry)
Range("J" & cTo).Value = stAry(cFm)
cTo = cTo + 1
Next
cTo = cTo + 1

End Sub

[ 続きを読む ]  返信件数:5件  [ 動画を見る] 

[7879]多次元配列_2

2017-03-30 12:09:20 平吹 敦史さんからの投稿です。

お世話様です。

好みの問題なのか、理由があるのか教えてください。
以下2つのsampleがあります。

結果はどちらも同じです。
違いは、配列変数の次元をどっちを先に書くかだけです。

先生の説明ですとsample1です。

個人的に理解しやすいのはsample2です。
理由は、行列のイメージに合うからです。

先生がsample1で指導される理由があり、今後の発展性も
踏まえて考えたときにどちらがベターか教えていただけると
助かります。

Sub Hairetu_Sample1()
Dim Arry(1, 12) As Variant
Dim cnt As Long
For cnt = LBound(Arry, 2) To UBound(Arry, 2)
Arry(0, cnt) = Range("C3").Offset(cnt).Value
Arry(1, cnt) = Range("D3").Offset(cnt).Value
Next

For cnt = LBound(Arry, 2) To UBound(Arry, 2)
Range("J3").Offset(cnt).Value = Arry(0, cnt)
Range("K3").Offset(cnt).Value = Arry(1, cnt)
Next
End Sub

Sub Hairetu_Sample2()
Dim Arry(12, 1) As Variant
Dim cnt As Long
For cnt = LBound(Arry, 1) To UBound(Arry, 1)
Arry(cnt, 0) = Range("C3").Offset(cnt).Value
Arry(cnt, 1) = Range("D3").Offset(cnt).Value
Next

For cnt = LBound(Arry, 1) To UBound(Arry, 1)
Range("J3").Offset(cnt).Value = Arry(cnt, 0)
Range("K3").Offset(cnt).Value = Arry(cnt, 1)
Next
End Sub

[ 続きを読む ]  返信件数:1件  [ 動画を見る] 

[7855]動的配列_3

2017-03-25 07:35:22 平吹 敦史さんからの投稿です。

お世話になっております。発展編1に引き続いてよろしくお願いします。
Chap02-41の演習で以下がどうしても理解できません。

Sub sample6() '静的二次元配列
Dim vList(1, 32) As Variant
Dim cnt As Long
For cnt = 0 To 32
vList(0, cnt) = Range("G2").Offset(cnt).Value
vList(1, cnt) = Range("H2").Offset(cnt).Value
Next

For cnt = LBound(vList, 1) To UBound(vList, 1)
Range("A2").Offset(cnt).Value = vList(0, cnt)
Range("B2").Offset(cnt).Value = vList(1, cnt)
Next

End Sub


Sub sample6() '静的二次元配列
Dim vList(1, 32) As Variant
Dim cnt As Long
For cnt = 0 To 32
vList(0, cnt) = Range("G2").Offset(cnt).Value
vList(1, cnt) = Range("H2").Offset(cnt).Value
Next

For cnt = LBound(vList,2) To UBound(vList, 2)
Range("A2").Offset(cnt).Value = vList(0, cnt)
Range("B2").Offset(cnt).Value = vList(1, cnt)
Next

①と②の違いはLBoundとUBoundの第二引数だけです。
左から数えて二次元目だから引数に2を入れるとのことですが、なぜ実行すると、
①は2行2列だけ(0と1)の反映になるのかが理解できません。

1次元目の最小値は0で最大値も32ではないのでしょうか?

よろしくお願いします。

[ 続きを読む ]  返信件数:3件  [ 動画を見る] 

[7245]動的配列_3

2016-10-30 17:38:38 田中 宏明さんからの投稿です。

扱うデータ数に応じて、配列の要素数を後から決定する方法「動的配列」を理解できました。
過去に自分が書いたマクロを見ていると、「静的配列」を「動的配列」に修正したくなります。

[ 続きを読む ]  返信件数:1件  [ 動画を見る] 

[7143]Functionプロシージャ演習中

2016-09-30 14:24:13 古口梨絵さんからの投稿です。

Functionプロシージャの演習について質問です。
抽象化というお話のなかで、
bgoukeiの第三引数を「3」、第四引数を「10」として設定していますが、「3」と「10」はどこから出てきた値なのでしょうか。
For Next構文から拾ってくるとすれば、「4」と「31」なのでは?と思うのですが。
実際にやってみると、やはり合計値が異なるので「4」と「31」かと。

[ 続きを読む ]  返信件数:3件  [ 動画を見る] 

[6813]モジュールレベル変数との使い分け

2016-07-02 00:33:58 受講生さんからの投稿です。

小川先生
こんにちは。VBA発展編2の動画を1通り勉強しました。
知識を定着させるために、テキストにある演習問題にとりかかっておりますが
色々なところ思考がとまってしまいヒントがほしいと思うことがあります。
模範解答はダウンロードする講座の資料の中にありますでしょうか。
また、発展2の知識定着のためにどのように復習すればいいかアドバイスありましたらお願いします。



[ 続きを読む ]  返信件数:1件  [ 動画を見る] 

[6524]引数として配列を受け取るFunctionプロシージャ

2016-04-26 20:18:31 ゲストさんからの投稿です。

小川先生へ

お世話になっております。
1点質問があります。
下記のサブプロシージャーに
(C-2)とありますが、-2は、なぜついているのでしょうか。
ご教授ください。
よろしくお願い致します。

Sub SetCampaignFlag()
    Dim stKonyuList() As String
    Dim c As Long
    For c = 2 To Range("F65536").End(xlUp).Row
        ReDim Preserve stKonyuList(c - 2)                               '←(質問箇所)こちらです。
        stKonyuList(c - 2) = Range("F" & c).Value
    Next
    
    For c = 2 To Range("B65536").End(xlUp).Row
        '以下のIf文の中で、関数からの戻り値を利用している
        If IsExists(Range("B" & c).Value, stKonyuList) Then
            Range("C" & c).Value = "○"
        Else
            Range("C" & c).ClearContents
        End If
    Next
End Sub

[ 続きを読む ]  返信件数:3件  [ 動画を見る] 

[5280]動的配列_3

2015-11-15 12:38:59 miendさんからの投稿です。

この動画の最後に説明している9月以降の祝日を抽出する演習問題についての質問です。
解答案のsub ccc()のコードについてホワイトボードのとおり書き写し、
実行したところ、「インデックスが有効範囲にありません」とのエラーがでました。
Forの前にReDim stHoliday(cm) As Stringを入れたら動きましたが、
If文の中のstHoliday = Range("H2").Offset(cnt).valueのところで
「型が一致しません。」とのエラーがでました。
stHoliday(idx)としてみたところ
元日から天皇誕生日までのすべての祝日を拾ってしまいました。

[Code]
Sub ccc()
Dim stHoliday() As String
Dim cnt As Long
Dim idx As Long
Dim cm As Long
cm = Range("H65536").End(xlUp).Row - 2
 ReDim stHoliday(cm) As String
For cnt = LBound(stHoliday) To UBound(stHoliday)
If Month(Range("I2").Offset(cnt).Value) >= 9 Then
ReDim Preserve stHoliday(idx)
stHoliday(idx)= Range("H2").Offset(cnt).Value
idx = idx + 1
End If
Next

For cnt = LBound(stHoliday) To UBound(stHoliday)
Range("L2").Offset(cnt).Value = stHoliday(cnt)
Next

End Sub
[/code]

そこで、上記のコードのIf Month(Range("I2").Offset(cnt).Value) >= 9 Then
をIf Month(Range("G2").Offset(cnt).Value) >= 9 Thenにしたところ、
エラーはでませんが、2009年と2010年の9月以降の祝日名が抽出されました。
問題の解答として合っていますでしょうか。

[ 続きを読む ]  返信件数:1件  [ 動画を見る] 

[5138]モジュールレベル変数との使い分け

2015-10-05 16:53:08 森 則彦さんからの投稿です。

 小川先生、お世話になっております。VBA上級コースの最後にある総合問題の問題5をやっとできました。
連想配列を関数にした引数として渡すのにちょっと苦労。結構、試行錯誤はしましたが、動いた時には超気持ちよかったです。
 外部連携講座を一通り受講しました。
知識がないままでしたので、ほとんど頭の中には残っていませんが、クラスとインスタンスの事が連想配列のCreateObject(”Scripting.Dictionary”)の
表現から何となくですが、感覚的にちょっとこんなものかな~と感じています。
 余談でしたが、話を元に戻します。
 データを全て取り込む Fuctionプロシージャ <データ取込> と、区名を調べ、種類とその数を連想配列使った  Fuctionプロシージャ <区名_取得>
とSubプロシージャ <レポート_区> という感じで作りました。
 オブジェクト変数は受け渡す度に Set 構文が必要かなという印象を受けました。まだ全てを経験したわけではないので確かなことは言えませんが。?
プロシージャの名前はあえて漢字にしました。引数の受け渡しが感覚的に目で見えるようにとの考えで。
下記にソースコードを載せておきますので、ご感想なりをお聞かせ願えるとありがたいです。
 追伸、
先生にお聞きしたいのですが、私個人の感想では、外部連携講座の基礎コースはさすがに敷居が高いので、
イベントとフォーム講座を先に勉強したほうが良かったかなという印象でおりますが、その辺はどうでしょうか?

code 
Function データ取込() As Variant()
Dim lIst() As Variant
Dim cR As Long, cL As Long, RMax As Long, LMax
Dim rG As Range
RMax = Range("a" & Rows.Count).End(xlUp).Row - 2
LMax = Cells(2, Columns.Count).End(xlToLeft).Column - 1
ReDim lIst(LMax, RMax)
Set rG = Range("a2")
For cR = 0 To RMax
For cL = 0 To LMax
lIst(cL, cR) = rG.Offset(cR, cL).Value
Next
Next
データ取込 = lIst
End Function


Sub レポート_区()
Dim kUrenn As Scripting.Dictionary
Set kUrenn = CreateObject("Scripting.Dictionary")
Dim aLllt() As Variant, kEylt() As Variant, cKen As Long, rKst() As String
Dim c1 As Long, c2 As Long, cNt As Long, rCnt As Long, kSt As String, kEnc As Long
Const rGsl As String = "i"
Const rGsr As Long = 2
aLllt = データ取込()
Set kUrenn = 区名_取得()
kEylt = kUrenn.Keys
With Range(rGsl & rGsr)
For c1 = LBound(kEylt) To UBound(kEylt)
kSt = kEylt(c1)
cKen = kUrenn.Item(kSt)
.Offset(cNt, 0).Value = kSt & "のマンションは" & cKen & "件ありました。"
.Offset(cNt, 0).Font.Bold = True
For c2 = LBound(aLllt, 2) To UBound(aLllt, 2)
kEnc = 0
If Not kEnc = cKen Then
If kEylt(c1) = aLllt(2, c2) Then
rKst = Split(aLllt(6, c2), "/")
.Offset(cNt + 1, 1).Value = aLllt(5, c2)
.Offset(cNt + 1, 2).Value = aLllt(3, c2)
.Offset(cNt + 1, 3).Value = aLllt(4, c2)
.Offset(cNt + 1, 4).Value = rKst(0)
.Offset(cNt + 1, 5).Value = rKst(1)
cNt = cNt + 1
kEnc = kEnc + 1
End If
End If
Next
cNt = cNt + 2
Next
End With
End Sub


Function 区名_取得() As Scripting.Dictionary
Dim kUlist As Scripting.Dictionary
Set kUlist = CreateObject("Scripting.Dictionary")
Dim RMax As Long, rG As Range, kUmei As String, rCnt As Long
RMax = Range("c" & Rows.Count).End(xlUp).Row - 2
Set rG = Range("c2")
For rCnt = 0 To RMax
kUmei = rG.Offset(rCnt).Value
If kUlist.Exists(kUmei) Then
kUlist.Item(kUmei) = kUlist.Item(kUmei) + 1
Else
kUlist.Add (kUmei), 1
End If
Next
Set 区名_取得 = kUlist
End Function
/code

[ 続きを読む ]  返信件数:1件  [ 動画を見る] 

[5054] 式と戻り値_3

2015-09-14 22:43:14 森 則彦さんからの投稿です。

Dim rg As Range, rg1 As Range
Set rg = Range("a1")
Set rg1 = Range("a2")
Range("c3") = rg + rg1

小川先生、お世話になっております。 森です
オブジェクトへの参照という概念は私なりに理解はしておりますが、上記のコードを走らせるとエラーもなく動きます。"a1" に 2 、"a2" に 3 を代入して動かすと"C3" に 5 という値が入ります。文字列型どうし、日付型どうしでも動きます。データ型が違う場合はエラーとなります。
これから推測するに、内部ではなるべく都合のいいように解釈しているのでしょうかね

[ 続きを読む ]  返信件数:1件  [ 動画を見る] 


各講座ごとのメッセージを見る場合はこちら

 

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

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

トップへ