Category Archives: サンプルコード・サンプルアプリ

VBAでの文字列同士の結合

達人養成塾の小川です。

受講者の方からの質問で、
次のようなコードをいただきました。

Sub Sample()
	Dim buf1 As String, buf2 As String
	buf1 = InputBox("数値1を入力してください。")  '100を入力
	buf2 = InputBox("数値2を入力してください。")  '200を入力
	MsgBox buf1 + buf2
End Sub

3行目と4行目でそれぞれ100、200と入力した場合、
5行目で何が表示されるでしょうか?

300って表示されるような気がしますが、
この場合は、「100200」というように
二つの数字がつながって表示されます。

通常、+の記号は足し算の記号で、
文字列を結合する場合は、&を使うのが一般的ですが、
文字列同士の場合は+でも結合されます

ここでは、2行目でbuf1, buf2の2つの変数が
Stringを使って文字列型に指定しているので、
文字列がつながって表示されるのです。

このようにVBAでは数値なのか文字列なのかによって、
同じ記号が別の意味になることがありますので、
知らずに使うと意図しない結果になりますので、注意が必要です。

以下のような検証のプログラムを実行してみて、
理解を深めてください。

プログラムの中に出てくるCInt関数は
文字列を整数に変える関数です。
これもよく使うので覚えておくと便利ですね。

Sub hoge()
    Dim s1 As String
    Dim s2 As String
    s1 = 1
    s2 = 2
    Debug.Print s1 + s2
    Debug.Print CInt(s1) + s2
    Debug.Print s1 + CInt(s2)
End Sub
 
Sub Sample()
    Dim buf1 As String, buf2 As String
    buf1 = InputBox("数値1を入力してください。")    '100を入力
    buf2 = InputBox("数値2を入力してください。")    '200を入力
    MsgBox buf1 + buf2
    MsgBox CInt(buf1) + buf2
    MsgBox buf1 + CInt(buf2)
End Sub

1900年3月より前での、VBAの日付型変数の値とエクセルに出力される日付との違いとその原因について

達人養成塾 小川です。

とある受講生からこんな質問がありました。

セルへの出力の場合、違った結果が表示されるのですね。
1900/1/1より前の日付だからでしょうか?…
http://www.exvba.com/comment_detail.php?comment_id=2704

何かというと。
たとえば、以下のコードを実行すると、セルA1には、「1900年1月0日 0:00」を意味する値が入る。

Dim d As Date
Range(“A1”).Value = d

ところが、以下のマクロを実行すれば分かるとおり、Visual Basic Editor上で比較すると、 初期値のままの日付型変数の値は、 1899年12月30日 0:00 と同値となっている。

    Dim d As Date
    If d = #1899/12/30# Then '[1]
        Debug.Print "一致"
    Else
        Debug.Print "不一致"
    End If

    'ただし、[1]の行の#シャープ#でくくられた部分は、
    '編集を終えた瞬間、以下のように置き換わってしまう。
    '#12:00:00 AM#

そこで、この点について整理して書いてみた。

ポイントは、以下。
○エクセルのうるう年の処理が間違っている(「1900年2月29日」という、ありえない日付がエクセルには存在する)
○そのため、1900年3月1日より後と1900年2月28日より前とでは、VBの中で日付型変数が持っている日付の値とそれを出力したときのエクセルでの日付が異なることがある。その逆もまた同様。

この件を明らかにするため、以下のマクロを書きました。

ただし、.text はセルに表示されている文字列をそのまま取得し、
.value はセルに入っている値を取得するという違いに留意しましょう。

Sub hoge1()
    Columns("B:C").ColumnWidth = 14
    Columns("B:C").NumberFormatLocal = "yyyy/m/d h:mm;@"

    Dim d As Date
    Dim c As Long
    
    If d = #12:00:00 AM# Then
        Debug.Print "一致"
    Else
        Debug.Print "不一致"
    End If
    For c = 1 To 3
        Range("A" & c).Value = c - 1
        Range("B" & c).Formula = "=A" & c
        With Range("C" & c)
            .Value = DateAdd("d", c - 1, d)
            Debug.Print c & "行目"
            Debug.Print vbTab & "excel value: " & .Offset(, -1).Value
            Debug.Print vbTab & "excel text : " & .Offset(, -1).Text
            Debug.Print vbTab & "dateadd    : " & DateAdd("d", c - 1, d)
            Debug.Print vbTab & "vba .value : " & .Value
            Debug.Print vbTab & "vba .text  : " & .Text
            Debug.Print vbNewLine
        End With
    Next
    For c = 60 To 62
        Range("A" & c).Value = c - 1
        Range("B" & c).Formula = "=A" & c
        With Range("C" & c)
            .Value = DateAdd("d", c - 1, d)
            Debug.Print c & "行目"
            Debug.Print vbTab & "excel value: " & .Offset(, -1).Value
            Debug.Print vbTab & "excel text : " & .Offset(, -1).Text
            Debug.Print vbTab & "dateadd    : " & DateAdd("d", c - 1, d)
            Debug.Print vbTab & "vba .value : " & .Value
            Debug.Print vbTab & "vba .text  : " & .Text
            Debug.Print vbNewLine
        End With
    Next
End Sub

このマクロの実行結果は、以下の通りです。

X202_000056

○出力結果

1行目
    excel value: 0:00:00
    excel text : 1900/1/0 0:00
    dateadd    : 0:00:00
    vba .value : 0:00:00
    vba .text  : 1900/1/0 0:00


2行目
    excel value: 1899/12/31
    excel text : 1900/1/1 0:00
    dateadd    : 1899/12/31
    vba .value : 1899/12/31
    vba .text  : 1900/1/1 0:00


3行目
    excel value: 1900/01/01
    excel text : 1900/1/2 0:00
    dateadd    : 1900/01/01
    vba .value : 1900/01/01
    vba .text  : 1900/1/2 0:00


60行目
    excel value: 1900/02/27
    excel text : 1900/2/28 0:00
    dateadd    : 1900/02/27
    vba .value : 1900/02/27
    vba .text  : 1900/2/28 0:00


61行目
    excel value: 1900/02/28
    excel text : 1900/2/29 0:00
    dateadd    : 1900/02/28
    vba .value : 1900/02/28
    vba .text  : 1900/2/29 0:00


62行目
    excel value: 1900/03/01
    excel text : 1900/3/1 0:00
    dateadd    : 1900/03/01
    vba .value : 1900/03/01
    vba .text  : 1900/3/1 0:00

「Is 演算子」と「Nothing」

達人養成塾 小川です。

イベントとフォーム講座の受講生から、こんな質問がありました。

「以下のif文について解説していただけると幸いです。
あまり見たことのないif文なのでよろしお願いします。

Dim r As Range

' ... 中略
' ... 中略
' ... 中略

If Not r Is Nothing Then

Else

End If

発展編1でくわしく取り扱っている内容ですが、ここでは、簡単にご説明。

Is 演算子は、比較演算子です。
つまり、 if hensu > 3 then とかいうときの「 > 」とかと同じ仲間です。

ただし、比較対象たる左辺、右辺とも、数字や文字、日付などのデータではなく、オブジェクトになります。

左辺で示されるオブジェクトと右辺で示されるオブジェクトが同じものなら True 、そうでなければ False という戻り値が得られます。

Nothing は、オブジェクト型の変数の初期値にもなっていますが、要は、「特にどのオブジェクトも示していない」という状態です。

最初にお見せしたサンプルコードに話を戻します。

ここで rはオブジェクト型の変数です。
「r Is Nothing」は、rの中身が空のとき True、すでに何らかのセルへの参照が設定されていたときには False を返します。
だから、「Not r Is Nothing」だと、その反対。rの中身が空のとき False、すでに何らかのセルへの参照が設定されていたときには True を返します。

この「 ~ Is Nothing」というパターンに慣れると、マクロを書くときのアイデアの幅も広がるでしょう。

ということで、最後に練習問題。
以下は、「is nothing」の参考例です。
アクティブなエクセルファイルに Sheet1, Sheet2 という2枚のシートがあるという前提で、以下の test1, test2 のマクロを実行した結果どうなるかを予測し、その後、実際に動作確認してみてください。

Sub test1()
    Dim w As Worksheet
    Set w = Worksheets("sheet1")
    If w Is Worksheets("sheet1") Then
        Debug.Print "同じです"
    Else
        Debug.Print "違います"
    End If
    If w Is Worksheets("sheet2") Then
        Debug.Print "同じです"
    Else
        Debug.Print "違います"
    End If
    If w Is Nothing Then
        Debug.Print "同じです"
    Else
        Debug.Print "違います"
    End If
End Sub
 
Sub test2()
    Dim w As Worksheet
     
    If w Is Worksheets("sheet1") Then
        Debug.Print "同じです"
    Else
        Debug.Print "違います"
    End If
End Sub

Dropboxのファイル競合を防ぐツールを作成しました

達人養成塾 事務局水谷です。
こんにちは。

Dropbox上でExcelファイル共有して作業しているとき、ファイルが競合してしまって困ったことはありませんか?
そんなお悩みを解消するために、小川がツールを作成しました。

このツールは誰かがファイルを開いているときに
同じファイルを他の作業者が開けなくするというマクロです。

使い方、サンプルコードについてはDropboxLock使いかた説明動画からダウンロード出来ます。
小川のの音声は入っていませんが、システム音は鳴ります。
http://youtu.be/qQSTpEikYEs

行動支援ツール「kodo」を一般公開します

エクセルマクロ・VBA 達人養成塾 小川です。

だいぶ前なのですが、今年のはじめにメールマガジン「%365 一日一歩のキャリアアップのヒント」の読者向けに公開したツールがあります。
今日は、それをこちらでもご紹介します。

エクセルVBAで動く、行動支援ツールです。

以下からダウンロードできます。
http://www.exvba.com/download/kodo/index.php?path=weblog

kodo_ver_1_1.zip というリンクをクリックすると、.zipファイルをダウンロードできます。

使い方の解説は、動画でしています。
こちらです↓。
http://video.exvba.com/kodo/kodo800/index.php?path=weblog

あと、エクセルファイル内にも、使い方の解説を書いています。

このツールは、「エクセルマクロ・VBA達人養成塾」代表小川慶一が、「ホリメソッド Nature Sleep School 天才育成カリキュラム」代表堀大輔さんの「行動活学メソッド」の手法をツールに落とし込むべく開発したものです。

「ホリメソッド Nature Sleep Schoolプログラム 天才育成カリキュラム」
http://www.horimethod.com/

ちなみに、この堀さんという人。

○一日に45分しか寝ない。「短眠」の天才にして指導者。(本人曰く、このくらいの睡眠時間のほうが健康なれるそうです)
○速読の天才にして指導者。年間読書数700冊。一日2冊は確実。
NHKの人気番組「ためしてガッテン」にも出演しても、
並み居る他の速読の達人を抑え、トップの速度と理解度。

という、そら恐ろしい人。ちなみに、高卒の29才。
知り合ったのは去年の春ごろですが、その後、いろいろ指導を受けています。

見た目は本当にフツーのちょっとおっとりした青年なのですが。

学んだことを体系化してコンテンツ化することの天才です。
特に、人が難しがっていることを簡単な練習方法に落とし込むことがめちゃくちゃ得意。

そしてそれだけではなく、着実に行動して人生を推し進めていく力のある人です。

「一見フツーそうなのにすごい」とは、まさにこの人のための言葉。

「見た目からすごそうなガツガツした営業マン」とか
「何百人もの人の前でも平気で講演できるエネルギッシュな人」、
「いかにも頭キレキレで、ちょっと触ったら言葉と目力でズタズタにされそうな人」
も怖いですが。

堀さんのような、「なんともなさそうだけど本当はすごい人」というのは、また違った恐ろしさを感じされられるものです。

それで、今、堀さんに指導を受けて生活のあり方、仕事の進め方の改善をしています。
今回お渡しツールは、堀さんのコンテンツのうち、「行動活学」という、行動して成果を出すためのノウハウの部分をツール化したもの。

年末からこのコンテンツについて教わり始めて実践しているのですが、確実に自分の人生が(特に深いところで)進み始めていることを、本当に実感しています。

考えすぎとか不安、先延ばし気質のせいでなかなか物事が進まないといった人、手帳術とかスケジュール管理術とかに興味はあるという人には超おすすめです。

堀さんのご許可をいただいたうえでちらとお話すると、安くないお金を払って堀さんから教わった「行動活学」のいちばん直接的な部分だけ要約すると

○決められたルーチン作業を毎日徹底してやること
○達成の基準を下げてでも、触れるべきものには毎日触れる

というものです。
(というのが、僕の解釈です。堀さん、違ったらゴメンナサイ)

「達成の基準を下げる」とは、どの程度のことを言うのかというと。

○「上体を鍛える」なら「腕立て伏せ一回」
○「朝の歯磨き」なら「はぶらしのほうに向かって歩く」
○「メールマガジンを書く」なら「元ネタ集のフォルダを開く」

とか、そのくらいのことです。最低そこまでやったらもう完了。
それ以上できたら万々歳!です。

誰でもできそうでしょ?

こんなことばかり書かれた行動リストを、まずは15個程度作ります。
それを、毎日少なくとも90%以上達成すること。

まず、3日これをきっちり続けてください。それだけで、たぶん半分は人生の加速が約束されたも同然です。

「そんなの、本当に意味あるのか?!」

と思われるかもしれません。

はい。僕も、指導を受けた当初は半信半疑でした。

でも、とにかく、やってみてください。
勘のいい人は、たぶん、やりはじめた3日後にはもう気づくと思います。

たぶん、3日くらいきっちりやり続けると、ある衝動が起こります。
そのあとのことは…。3日やった人にだけお知らせしますので、それ以降のタイミングで僕にメールしてください。
(意地悪しているんじゃありません。そのタイミングで僕が伝えたいことは、3日やった人でないと話しても伝わらない内容なのです)

その衝動と、それにどう対応すべきかということが分かれば、「あとはもう、好きにしてくれ!」という感じです。

僕も、3日やったところで「これは、相当にヤバい (@_@; 」と実感できました。

それで、「この手法をツールに落とし込もう!と開発着手したのが、今回お配りするツールです。

ついでに、「毎日の行動」ではなく、「単発の行動」や
「週1回やること」、「月1回やること」といった
期間が空く行動にも活用できるようにしたり、
人に依頼したまま返事が来るまで再開できない行動も管理できるようにしたり、と
やっているうちに、ツールとしての利便性が増してきまして。

今では、ディビット・アレン提唱の「GTD」に近い性質の行動支援ツールになっています。

堀さんとは、毎日夜、行動リストに対する進捗を報告することになっています。
それで毎日このツールを使って行動の報告をしていたのですが、堀さんも使い始めてくれました。
いまでは、それまで使っていた iPhone アプリのタスク管理ツールを捨てて、今回お渡しするツールだけで行動していらっしゃいます。

僕が堀さんに紹介したお客さんや、僕の講座受講生のうちでも特に勘のいい人たちにお見せしているのですが、

もう、一様に、

「絶対にそれ欲しい!!いますぐ!!」と。

(堀さんもこのツールについてはお話をされているそうです。とある堀さんの講座の受講生にお話したら、「それって何万円ですか?」と聞かれたとか )

「行動支援ツール kodo」は、以下からダウンロードできます。
http://www.exvba.com/download/kodo/index.php?path=weblog

まずは、 .zip ファイル内のエクセルファイル kodo.xls 内の、シート「current」の中身を見てみてください。

その内容を参考に、オリジナルの行動リストを15個程度作ってください。
あとは90%以上の達成率を維持しつつ、まずは3日やってみるだけです。

ぜひ、徹底活用して、2013年をより充実したものにしてください。

ということで、新春プレゼントのご案内でした。
今日は、ここまで。

..ということで。
このツール、その後も改善を続けていて、最新版は僕と堀さんが持っています。

あと、「kodo」は機能が多すぎて使い方が分からない!という方向けの、超簡易版も。

最新版とか超簡易版とかもそのうちみなさんにお見せしようかとは思っていますが、ご興味おありの方は個人的にご連絡ください。

ではでは。

100マス計算問題解答ジェネレータ作りました。

とある受講生が100マス計算を自動で行うマクロを作った、とメールをくれて見せてくれた。
それを見て触発されて、僕も作ってみた。

なかなか会心のデキ。教育機関のみなさんのお役に立つと思います。さしあげますので自由に使ってください。

以下からダウンロードできます。
100マス計算問題解答ジェネレータ

カレンダー・予定表を作るExcel VBAプログラム – エクセルマクロ達人養成塾

Excelマクロ・VBA達人養成塾 小川です。

エクセルマクロ達人養成塾塾長ブログ-最上川。8月上旬、山形に遊びに行きました。
最上川。8月上旬、山形に遊びに行きました。

タイムトライアル。第6弾。

エクセルファイル「master.xls」に、予定表のテンプレートとして以下の体裁のエクセルシートがある。
エクセルマクロ達人養成塾塾長ブログ-テンプレートのシート
このリンクをクリックすると、マスターファイルをダウンロードできます

ここで、このシートをテンプレートとして、2013年1月~12月の予定表を作りたい。
(各月のファイルは、1月なら1日~31日、2月なら1日~28日のシートを作る)

ということで、やってみてください。
ちなみに、特別ひっかかったところはなかったのですが、僕がかかった時間は、14分でした。

達人養成塾発展コース修了生向けに書くと、やり方というか発想は、「伝票作成マクロ」といろいろなところで似ています。

チャレンジされて、その結果をご報告いただいた方には、いつもどおり、僕が実際に作業したときにキャプチャーした動画をさしあげます。

期限は特にさだめませんが、9月第二週末くらいまでにはやってもらいたいところ。
(でないと、僕が、動画をどっかにやってしまうかも (^^; )


お知らせというか、打診です。

ひさしぶりに、以下のセミナーやろうかと検討中です。
どれかに、ご興味おありの方、どのくらいいらっしゃいますかね。

イヤでもWindows操作とExcel操作が早くなるワークショップ
http://www.exvba.com/closed/moushikomi_winxls.php

親指シフト達人養成塾
http://www.exvba.com/oyayu/index.php

Excelデータ分析7つの上級技
http://www.exvba.com/exbunseki/index.php

今のところ実施予定日は、僕の中では以下の感じ:

イヤでもWindows操作とExcel操作が早くなるワークショップ
東京9月29日

親指シフト達人養成塾
東京9月30日、大阪11月10日

Excelデータ分析7つの上級技
東京9月30日、大阪11月10日


エクセルVBAで図形を操作するときの注意点

エクセルマクロ・VBA達人養成塾 小川です。

明日(14日)から、休暇を取って、キューバに行ってきます。

今日は、その前の、最後のブログです。

とはいえ、僕がいない間も、ブログは更新されるよう、ネタは書きためてありますので。
ご安心ください(?)

期待されていた方がどのくらいいるかは分かりませんが ヾ(´ー`)ノ

さてさて、そんなわけで。

今日は、先日のエクセルマクロ・VBAセミナー発展コースで使ったサンプルを、ひとつ紹介。

シート上の図形を操作するプログラムです。以下では、シート「Sheet3」にある複数のオートシェイプのうち、名前が、「角丸四角形 1」ではないものだけを選び、その色を変更しています。

Sub aglegte()
Dim sp As Shape
For Each sp In Worksheets("Sheet3").Shapes
Debug.Print sp.Name
If Not sp.Name = "角丸四角形 1" Then
sp.Fill.ForeColor.RGB = RGB(256, 0, 256)
End If
Next
End Sub

ここで重要なのは、「オートシェイプ」のような図形ものについては、たとえ、今表示されているシート上のものだったとしても、

Worksheets(“Sheet3”).Shapes

のように、「どのシート上の」ということを明示しなくてはならない、ということです。

その点、エクセルのセルを操作するときとは違いますね。

エクセルVBAでのオブジェクト操作を覚えたてのことは、シートを明示しなければならないことをうっかりして、失敗しがちです。
気をつけてくださいね。

自分も周りもびっくりしました。感動です。

エクセルマクロ・VBA達人養成塾 小川です。

大阪にいます。

そして、ちょっと、風邪気味です。。

先日、引きこもって仕事をしていた喫茶店で、クーラーがちょっと効き過ぎててイヤだな、と思っていたのですが。。

どうも、その延長で、という感じのようです。

あいたたた。

来週から休暇ということでキアイを入れて仕事をしたかったのですが、今日は、昼過ぎに都内で打ち合わせをした以外、特に何もできませんでした。。

さてさて。

そんなわけで(どんなわけだ?)今日は、受講生から今日もらった声をひとつご紹介。
フォローアップでお送りしている動画セミナーへのフィードバックのついでにいただいた声です。

セミナー受講後まだ5日の方です。

今回の問題について、先生のおっしゃった”数列”のところを一次の連立方程式を解くような感じで手で計算してやってみました。でも解説をみて、具体的にRange(” ”)を並べてみるほうが直観的でわかりやすいですね。マクロの内容を理解することはもちろんのこと、マクロを書くスピードや、マクロを実行したときにコンピュータが作動するスピードも気を付けていきたいと考えます。

(ちなみに昨日初めて業務でマクロを試作し同僚に披露してみました。自分も周りもびっくりしました。感動です。)

ここで言う「数列」というのは何かというと。

1行目、3行目、5行目、… というように、飛び飛びのセルにデータが入っている場合に、

sub hoge()
dim c as long
     for c = 1 to 10
        range("F" & c).value = range("A" & c * 2 - 1).value
     next
end sub

みたいな感じでデータを処理するとき、どうやって

c * 2 – 1

という式を求めるのか、という話です。

こういうとき、どうするかというと。

オススメは、For Next構文を作る前に、まずは、ベタに書いてみる。

↓こんな感じ。

Range("F1").Value = Range("A1").Value
Range("F2").Value = Range("A3").Value
Range("F3").Value = Range("A5").Value
Range("F4").Value = Range("A7").Value
Range("F5").Value = Range("A9").Value

そして、しばらくじーっと見て、右辺に、

c * 2 – 1

という法則を見いだします。

こういうのは、人がやった事例を見て、「へー、こういう方法があるのか!ふんふん!」と学んでいくのが上達の近道ですね。

そんなわけで、達人養成塾では、セミナー修了生向けに、動画を使って、いろいろ実データにありがちなサンプルを使って、僕が実際にマクロを書いていき、解説をする、というもの教材を用意しています。

さいきん数えてみたのですが、基礎コースだけでも、全18回、合計199分28秒あるようです。

これだけでも、フツーのセミナー一日分くらいの分量ですね ヾ(´ー`)ノ

あと、このSさん。
セミナー受講後まだ5日なのですが、さっそく実務でマクロを書いてみて、「自分も周りもびっくりしました。感動です」とのこと。よかったです ヾ(´ー`)ノ

.Value, .Formula, .FormulaR1C1

http://www.exvba.com/vb/index.php
エクセルマクロ・VBA達人養成塾 小川です。

今日は、ときどきいただく質問をご紹介。

セルに関数が入っている場合の処理について。

例えば、セルI4に「=Sum(C4:H4)」という数式が入っている。
その結果、セルI4には、「21」という値が表示されている。

このとき、「数式」を取ってきたい、または、「値」を取ってきたい、というとき。

どうやって、切り分けるか。

結論から言うと、.Valueと.Formulaを使い分ける。

Sub valueformulatest()
    Range(“K4″).Value = Range(“I4″).Value     ‘「値」を取ってくる
    Range(“L4″).Value = Range(“I4″).Formula ‘「式」を取ってくる
    Range(“M4″).Formula = Range(“I4″).Value ‘「値」を取ってくる
    Range(“N4″).Formula = Range(“I4″).Formula ‘「式」を取ってくる
End Sub

この結果、セルK4~N4に入るのは、以下の数式または、値

セルK4: 21
セルL4: =SUM(C4:H4)
セルM4: 21
セルN4: =SUM(C4:H4)

これが何を意味するのかというと。

[1] .Valueで設定しても、.Formulaで設定しても、違いはない。
[2] .Valueで取得すると「値」、.Formulaで取得すると「式」を取得するという違いがある

ということ。

ついでに、.FormulaR1C1についても、簡単に解説。

.FormulaR1C1は、式を相対参照で取得します。

何のことやら?ということでしたら、以下を参考にしてください。

Sub formula_formular1c1()
    Range(“I5″).Formula = Range(“I4″).Formula ‘セルI5に入るのは、「=SUM(C4:H4)」という式。
    Range(“I6″).FormulaR1C1 = Range(“I4″).FormulaR1C1 ‘セルI6に入るのは、「=SUM(C6:H6)」という式。
End Sub