プログラム作成時 Ctrl+C Ctrl+Vの前によく考えよう

[VBA系メニューへ] [質問掲示板] [バックナンバー目次]




こんにちは、三流プログラマーのKen3です。

三流君の書いてるメルマガ
http://www.ken3.org/guchi/    作者の貧しい心の中が見れる愚痴系
で、
自分の貧しい技術に対する愚痴で書いたんだけど、
愚痴系で発行後、読み直すと、
VBA系の読者に見せたほうが、よさそうだったので、
こっちでも発行してます。
※愚痴系、VBA系読んでて、重複してしまった人はスミマセン。

三流君のお馬鹿な開発話を笑ってください
※反面教師でマネしないでね。

--- ここから はじまりです ---

どちらかと言えば、芸術的プログラムとは無縁の三流プログラマーです。
えっ、そんなのわかってるって?

そんな前フリは置いといて、
今回は、
Ctrl+C + Ctrl+V を使う前に一呼吸置こうよ
コピーして編集するプログラムは工夫できる率が高いよ
って話です。

まぁ、いつもの独り言だけど、聞いてください。

/* * 1.今回のキッカケ */

VBA系のメルマガで、And演算子、Not演算子の解説を行ってました。 自己レスじゃないけど、フトお馬鹿なことに気がつく。 ※いつになったら、手前味噌的な自慢系のメルマガに成長できるのだろう(笑)  オレ様のプログラムってキレイだろ、芸術品だよ、、と  いつか自信を持って、言って見たいよね。。。 おっと、挨拶はこれくらいにして、

/* * 2.コピー -->貼り付け で作るプログラムの罠(笑) */

No.76 Access レポート Me.NextRecord = Falseで移動を止める http://www.ken3.org/backno/backno_vba16.html#76 左端ならラベルを表示、レコード移動を止め次に実データを印刷する そんなテストプログラムなのですが、 初めは下記のように、普通に作成してました。
Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    If (Me![cntA] Mod 3) = 1 Then  '左端なら
        If pFLG = False Then 'まだラベルエリアを印刷してなかったら
            Me.NextRecord = False      'レコードの移動をまず止める
            pFLG = True  '印刷フラグを立てる
               'ここにラベルのOn/Off処理を入れる
            Me![lab01].Visible = True
            Me![lab02].Visible = True
               '実データをOff  <−−−注目(笑)
            Me![ID].Visible = False
            Me![WrietTime].Visible = False
            Me![F_TITLE].Visible = False
            Me![F_MEMO].Visible = False
        Else
               'ここにラベルのOn/Off処理を入れる
            Me![lab01].Visible = False
            Me![lab02].Visible = False
               '実データをOff  <−−−注目(笑)
            Me![ID].Visible = True
            Me![WrietTime].Visible = True
            Me![F_TITLE].Visible = True
            Me![F_MEMO].Visible = True
        End If
    Else
        pFLG = False  'その他の時
    End If

End Sub
よく見ると、同じような処理があって、 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'ここにラベルのOn/Off処理を入れる Me![lab01].Visible = True と Else 'ここにラベルのOn/Off処理を入れる Me![lab01].Visible = False みたいな感じでOn/Offが逆なだけでした。 まぁ、処理が 左端ならラベルを表示、実データは非表示、 その他はラベル非表示、実データを表示だから、 True/Falseが違うだけで同じなんですよね。 そっか、それで、キーボードでCtrl+C,Ctrl+Vでコピーして、 True/Falseを逆に書いたんだ。 えっ、なんでCtrl+C,Ctrl+Vでコピーしたってわかったの? だってさ、コメントが直ってないんだよ、アンタのコメントが? えっ、どこどこ? よく見ろよ、 If pFLG = False Then 'まだラベルエリアを印刷してなかったら Me.NextRecord = False 'レコードの移動をまず止める pFLG = True '印刷フラグを立てる 'ここにラベルのOn/Off処理を入れる Me![lab01].Visible = True Me![lab02].Visible = True '実データをOff <−−−注目(笑) Me![ID].Visible = False Me![WrietTime].Visible = False Me![F_TITLE].Visible = False Me![F_MEMO].Visible = False と Else 'ここにラベルのOn/Off処理を入れる Me![lab01].Visible = False Me![lab02].Visible = False '実データをOff <−−−注目(笑) Me![ID].Visible = True Me![WrietTime].Visible = True Me![F_TITLE].Visible = True Me![F_MEMO].Visible = True End If を良く見ると、 '実データをOff ^^^^^^^^^^^^^^^^^ ってコメントが一緒だよ。 Elseの部分のコメントは、実データをon、可視にする ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ が正しいんじゃないの? コピーして作るのもいいけど、直してね、 コメントだから、まだ実害なかったけど、 もし、TrueとFalseを逆にするのを直し忘れてたら? ゾッとするよね。 最近の開発スタイルって、エディターに直打ち、即実行確認、 なんて環境だから、 一呼吸置いて、考えないでコピー、貼り付けって多いと思う。 で、コピーした一部(部分的範囲)を変更する。 修正中にメールや携帯が鳴って、割り込みが入り作業中断、 そしたら、修正忘れがあったり、、なんて変なストーリーあったりしてね。 たまたま、今回は、 VBA系の No.77 Not演算子で細工する、プログラムはパズルのように... http://www.ken3.org/backno/backno_vba16.html#77 で、 Not演算子を使用して下記のようにまとめてみたけど、 何も考えないと、私のように同じ処理が氾濫してたりするよ(笑) 手前味噌、芸術的、ナルシスト的プログラムって言われてもたまには作ってみようよ。
Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    If (Me![cntA] Mod 3) = 1 Then  '左端なら
        'フラグを使用して可視/不可視をセットする
        Me![lab01].Visible = Not pFLG  'ラベルはフラグの逆をセット
        Me![lab02].Visible = Not pFLG
        '実データ
        Me![ID].Visible = pFLG         '実データにはフラグそのままセット
        Me![WrietTime].Visible = pFLG
        Me![F_TITLE].Visible = pFLG
        Me![F_MEMO].Visible = pFLG
        
        If pFLG = False Then 'まだラベルエリアを印刷してなかったら
            Me.NextRecord = False      'レコードの移動をまず止める
            pFLG = True  '印刷フラグを立てる
        End If
    Else
        pFLG = False  'その他の時
    End If

End Sub
と、Not演算子を使用して、まとめました。 これなら、項目の1つだけTrue/Falseの修正忘れの単純ミスもないし、 項目が増えても、2ヶ所に処理を入れなくてOKです。

/* * 3.プログラムには、ループや配列を使った処理が存在するんだよ(笑) */

画面に1回目、2回目、、4回目とMsgboxで表示してよと言われたら、 簡単なプログラムは、
Sub AAA()
   Msgbox "1回目"
End Sub
って書いてから、いつものCtrl+CでコピーCtrl+Vを3回押してと
Sub AAA()
   Msgbox "1回目"
   Msgbox "1回目"
   Msgbox "1回目"
   Msgbox "1回目"
End Sub
としてから、
Sub AAA()
   Msgbox "1回目"
   Msgbox "2回目"
   Msgbox "3回目"
   Msgbox "4回目"
End Sub
と直します(笑) そんなことしないよFor文使うよ ~~~~~~~~~~~~~~~~~~ って、みなさん、心の中で言ったと思います (私が勝手にアナタの心の中を予想しました) ですよね、まぁ、コピー、一部変更プログラム極論でした。 では、チエちゃん好き、ミキちゃん好き、アキちゃん好き、マイちゃん好き と名前を出すときは?
Sub AAA()
   Msgbox "チエちゃん好き"
   Msgbox "ミキちゃん好き"
   Msgbox "アキちゃん好き"
   Msgbox "マイちゃん好き"
End Sub
じゃなくって、
Sub BBB()

    Dim strNAME As Variant
    Dim n As Integer
    '配列を代入
    strNAME = Array("チエ", "ミキ", "アキ", "マイ")
    'データを表示
    For n = 0 To 3
        MsgBox strNAME(n) & "ちゃん好きです"
    Next n

End Sub
と、ループとArrayで配列を作成の知識のある人は作るかな。

/* * 4.配列の要素数を返すUBound関数を使ったりする */

表示させたい、好きな子が増えたら? コピー君は、
Sub AAA()
   Msgbox "チエちゃん好き"
   Msgbox "ミキちゃん好き"
   Msgbox "アキちゃん好き"
   Msgbox "マイちゃん好き"
   Msgbox "アヤちゃん好き"  '午後の紅茶のアヤちゃんは好きじゃないけど(笑)
End Sub
とコピーで作成するのかな。 For君は、
Sub BBB()
    Dim strNAME As Variant
    Dim n As Integer
    '配列を代入
    strNAME = Array("チエ", "ミキ", "アキ", "マイ", "アヤ")
    'データを表示
    For n = 0 To 4 'カウンタも忘れずに増やす
        MsgBox strNAME(n) & "ちゃん好きです"
    Next n
End Sub
とデータとカウンタを増やすのかな。 まぁ、忘れそうなのが、データ増やしてカウンタを増やすことを忘れるパターン。 それを防止する方法?があって、 昔からの古典的手法は データの最後に"END""STOP","99"など、 ストップワードを入れて判断する方法もある。
Sub CCC()
    Dim strNAME As Variant
    Dim n As Integer
    '配列を代入
    strNAME = Array("チエ", "ミキ", "アキ", "マイ", "アヤ", "STOP")
    'stopまでデータを表示
    n = 0 'カウンタ初期化
    While strNAME(n) <> "STOP"  'STOP以外の間ループする
        MsgBox strNAME(n) & "ちゃん好きです"
        n = n + 1  'カウントアップ次の子にする
    Wend
End Sub
これだと、ループの回数は指定しないで、"STOP"までループ可能。 まぁ、今風の書き方だと、配列の最大要素数を求めるUBoundって関数があって、
Sub DDD()
    Dim strNAME As Variant
    Dim n As Integer
    '配列を代入
    strNAME = Array("チエ", "ミキ", "アキ", "マイ", "アヤ")
    'データを表示
    For n = 0 To UBound(strNAME) '配列の最大要素までループ
        MsgBox strNAME(n) & "ちゃん好きです"
    Next n
End Sub
ASPで作った例だけど、Split関数とUBound関数のサンプル http://www.ken3.org/cgi-bin/test/test024-2.asp こっちも参考にしてみてね。

/* * 5.コントロールをループさせる For Each IN を使って */

この流れの解説だと、(話の流れだと) 読者の心の声をまたまた勝手に代弁すると、 ^^^^^^^^^^^^^^ データをプログラム内に持たないで、ファイルなど外部に持つ方法だろ、、 と 普通は来るのですが、疲れたので、今日は辞めます(笑) オイオイ、そりゃないでしょ。 えっと、このメルマガのタイトルに戻って、 タイトル?なんだっけ? 三流君、手前味噌的にプログラムを語る?だったっけ・・・ 違うでしょ、 Ctrl+C + Ctrl+V を使う前に一呼吸置こうよ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ってタイトルです。 下記のプログラムに戻ってと、 実は、ここでもCtrl+C Ctrl+Vでプログラム書いてるんですよね。 Me![ID].Visible = pFLG をコピーして、 Me![F_TITLE].Visible = pFLG Me![F_MEMO].Visible = pFLG なんて、作ってるんですね。 ※フィールド名が違うだけなので、コピーしてフィールド名を修正するかな普通。
Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    If (Me![cntA] Mod 3) = 1 Then  '左端なら
        'フラグを使用して可視/不可視をセットする
        Me![lab01].Visible = Not pFLG  'ラベルはフラグの逆をセット
        Me![lab02].Visible = Not pFLG
        '実データ
        Me![ID].Visible = pFLG         '実データにはフラグそのままセット
        Me![WrietTime].Visible = pFLG
        Me![F_TITLE].Visible = pFLG
        Me![F_MEMO].Visible = pFLG
        
        If pFLG = False Then 'まだラベルエリアを印刷してなかったら
            Me.NextRecord = False      'レコードの移動をまず止める
            pFLG = True  '印刷フラグを立てる
        End If
    Else
        pFLG = False  'その他の時
    End If

End Sub
このプログラムでもいいんだけど、 実データの印刷フィールドが追加になったら、(F_TAKOフィールド) Me![F_TAKO].Visible = pFLG と、プログラムの追加が発生します。 ※これも、上の一行Me![F_MEMO].Visible = pFLGをコピー後に名称変更かな フィールドが追加になったから、ショウガナイヨネ、これは。 まぁ、そうなんですが、よく見ると、 Me![lab01]とMe![lab02]のラベル関係 と 実データのMe![F_XXXXX]の実データ関係 そんな2つのグループ分けができてます(IDとwriteなど例外あるけど(笑)) コントロールの名前付けで、 規則性があるなら、ループでまわせよってことで、 ↑~~~~~~~~~~~~~~~~(コントロール名を規則正しく作ってね) Controlsコレクションでまわしてみます。 Controls?コレクション? コントロールにアクセスする方法は、 Me.Controls!新規データ Me.Controls![新規データ] Me.Controls("新規データ") なんて、名前を指定する方法と、 インデックスでコントロールを参照することもできます。 Me(0) ' コレクションの最初の項目を参照します。 Me.Controls(0) これを利用して、
Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    Dim n As Integer
    If (Me![cntA] Mod 3) = 1 Then  '左端なら
        For n = 0 To Me.Controls.Count - 1 'コントロールの数ループする
            If Left(Me.Controls(n).Name, 3) = "lab" Then '名前はラベル
                Me.Controls(n).Visible = Not pFLG
            Else
                Me.Controls(n).Visible = pFLG
            End If
        Next n
        If pFLG = False Then 'まだラベルエリアを印刷してなかったら
            Me.NextRecord = False      'レコードの移動をまず止める
            pFLG = True  '印刷フラグを立てる
        End If
    Else
        pFLG = False  'その他の時
    End If
End Sub
と書いて、 コントロールの名前付けの規則でTrue/False を 切り替える方法も1つの手です。 Me.Controls(n).Visible あっ、これが三流君のうわさのクセね。 ループのカウンタでまわしたがるってヤツね。 VBA系の No.73 オブジェクトのループはFor Each In でループさせる http://www.ken3.org/backno/backno_vba15.html#73 で、 偉そうなこと語ってて、これかよ。 ~~~~~~~~~~~~~~~~~~~~ わかったよ、一般向けにFor Each版に修正するよ。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    Dim objITEM As Object  'コントロールのオブジェクトを入れる変数
    If (Me![cntA] Mod 3) = 1 Then  '左端なら
        For Each objITEM In Me.Controls 'コントロールを取り出しループする
            If Left(objITEM.Name, 3) = "lab" Then '名前はラベル
                objITEM.Visible = Not pFLG
            Else
                objITEM.Visible = pFLG
            End If
        Next

        If pFLG = False Then 'まだラベルエリアを印刷してなかったら
            Me.NextRecord = False      'レコードの移動をまず止める
            pFLG = True  '印刷フラグを立てる
        End If
    Else
        pFLG = False  'その他の時
    End If

End Sub
これなら、ラベルと実データの切り替えも、 コントロール名の規則にしたがって作成すれば、 変更の少ないプログラムで済みますね。

/* * 6.終わりの挨拶(次回はアルのか?(爆)) */

よくわからなかったけど、何が今日は言いたかったの? えっと、 Ctrl+C , Ctrl+V でサクサク?コーディングするんだけど、 ちょっと待てよ、 コピー、貼り付け、一部変更、 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ なんてプログラムには、一工夫する余地があるのでは? って話でした。 まぁ、キーボード打つのが早い、エディター使うのが早い そんな若いプログラマーにトータル的に勝つには、 変更が来たとき、キーボード打量を減らす(もしくは打たなくていい) そんなプログラム作りたいよね、 30代のキーボード打ち込み遅いおっさんプログラマーとしては(爆) 何か読者の心に残れば、うれしいです。 *私の独り言をうまく消化してくださいね。 手前味噌プログラム発表したいよねのKen3でした。 ~~~~~~~(↑オイオイ)

質問・感想を送る

作者に感想・質問/要望を送る(気軽に質問・感想書いてください)
あなたのお名前(ニックネーム) さん

作者からの返信は、 不用 E-mail で受信したい

三流君のHP主な飛び先

VBA系のメルマガで書いた解説を項目ごとにまとめてます

[VBAでAccessを操作(一般)]
[VBAでAccessのレポートを操作]
[VBAでAccessのUserForm/サブフォームを操作]
[VBA Access から Excel 連携]

[VBA でExcel オブジェクト/プロパティ/メソッド/一般]
[VBA でExcel UserForm(ユーザーフォーム)を操作する]
[VBA ExcelからAccessを操作する]

[VBA Outlookの操作]
[VBA IEの操作]
[VBA テキストファイル(*.txt,*.html,*.csv)の操作]
[VBA標準関数関係とその他解説]

ASP系の解説を項目ごとにまとめてみました

[ASP Form等を使用したデータのやり取り]
[ASP その他処理サンプル]
[ASP テキストファイル処理]
[ASP VBScript関数関係の説明]
[ASP ADOでMdbファイルを使う]
[ASP ADOでExcelと接続してみた]

分類別

[アクセスランキング] [サイトマップ] [リンク先・相互リンク先など]
VBAで楽しくプログラミング 掲示板 バックナンバー メルマガ登録と解除
コンビニのオモテとウラ話 掲示板 バックナンバー メルマガ登録と解除
ASPで遊ぶ、失敗する 掲示板 バックナンバー メルマガ登録と解除
三流プログラマー 業務の愚痴 掲示板 バックナンバー メルマガ登録と解除
初心者にやさしいプログラム 掲示板 バックナンバー メルマガ登録と解除
ネットで稼ぐ本音と失敗談 掲示板 バックナンバー
www.ken3.org(サイト内)から Google を利用して、

Ken3の日記(weblog) -- [広告・副収入系] [プログラマー業務の愚痴] [VBA系の話題] [ASP系の話題] [コンビニ系ネタ] [その他]

その他、宣伝ページです

・[ アンケート/ポイント]などで月500円を必死に稼いでます(笑)
・[ SOHO/在宅プログラマー/派遣]の話題、Webエントリー後の反応など
・[ ネットで小金を稼げるか?]実験中だが成果は無し
※あとは、[パソコン関係の書籍]や[ゲームソフト]、 [パソコンパーツ] をバナーから売ろうとするけど、
 なかなかうまくはいかないよね(笑)

楽天の商品売れ筋ランキング紹介ページ

ドリンク

[コーヒー・ココア] [ソフトドリンク] [ハーブティー] [ビール・地ビール] [ワイン] [中国茶] [中国酒] [日本茶] [日本酒] [水・ミネラルウォーター] [洋酒] [焼酎] [紅茶] [その他(ドリンク)]

グルメ・フード

[キムチ・漬け物] [チーズ・乳製品] [パン] [フルーツ・野菜] [] [惣菜・食材] [中華料理・惣菜] [和風料理・惣菜] [洋風料理・惣菜] [水産物・水産加工品] [] [肉・肉加工品] [菓子] [調味料] [麺類] [その他(フード)]

ファッション

[インナーウェア・ナイトウェア] -- [ショーツ] [ブラジャー] [ストッキング] [キャミソール] [スリップ] [ガードル] [補正下着] [マタニティ用下着] [ナイトウェア]
[カジュアル] -- [Tシャツ] [シャツ] [カットソー] [セーター] [カーディガン] [ジーンズ] [パンツ] [ジャンバー・ブルゾン] [スカート]
[レディース・婦人服] -- [スーツ] [ワンピース] [スカート] [パンツ] [ブラウス] [フォーマル]
[ジュエリー・アクセサリー] -- [指輪] [ネックレス] [ペンダント] [イヤリング] [ピアス] [ブレスレット] [ジュエリーボックス・ケア用品]
[香水] -- [シャネル] [クリスチャン・ディオール] [ジバンシー] [グッチ] [ブルガリ]
[メンズ・紳士服] [メンズ-スーツ] [メンズ-シャツ] [メンズ-トランクス] [メンズ-ブリーフ] [メンズ-ボクサーパンツ] [メンズ-Tシャツ] [トレーナー・パーカー] [メンズ-ポロシャツ] [メンズ-カットソー] [メンズ-セーター] [メンズ-カーディガン] [メンズ-ジーンズ] [メンズ-ジャンバー・ブルゾン]
[バッグ] [] [ベビー・キッズ・マタニティ] [和服] [眼鏡・サングラス] [コンタクト・コンタクト用品] [腕時計] [雑貨・小物] [スイムウェア]

パソコン・家電・AV

[オフィス・サプライ] [コンパクトカメラ] [デジタルカメラ] [ビデオカメラ] [一眼レフカメラ] [ソフトウェア] [パソコン・コンピュータ] [デスクトップパソコン] [ノートパソコン] [モバイル・携帯電話] [周辺機器パーツ] [スキャナ] [プリンタ] [家電・AV] [エアコン・空気清浄機] [オーディオ] [冷蔵庫・冷凍庫] [掃除機] [映像機器]

生活・インテリア

[家具・インテリア] [手芸・クラフト] [文具] [日曜大工・作業用品] [日用品・生活雑貨] [食器・調理用具]

ヘルス・ビューティ

[ダイエット] [健康用品] [サプリメント] [医薬品] [福祉・介護] [美容・化粧品] [スキンケア] [メイクアップ]

スポーツ・アウトドア

[アウトドア] [ウィンタースポーツ] [サッカー] [ストリート系スポーツ] [テニス] [トレーニング] [フィッシング] [マリンスポーツ] [自転車] [野球] [スポーツグッズ] [格闘技グッズ] [その他スポーツ・用品]

フラワー・ガーデン

[エクステリア] [ガーデニング] [フラワー・花] [植木] [観葉植物] [造花]

ホビー・ペット・コレクション

[アート・美術品] [おもちゃ] [ペット・ペットグッズ] [占い・開運] [囲碁・将棋] [楽器] [趣味・コレクターグッズ]

CD・DVD・ゲーム

[CD・カセット] [DVD・LDソフト] [アニメ(DVD・LD)] [ミュージック(DVD・LD)] [洋画] [邦画] [テレビゲーム] [ビデオ] [音楽CD] [R&B] [アニメソング] [ジャズ] [ダンス&ソウル] [ヒップホップ] [ロック・ポップス(洋)] [ロック・ポップス(邦)]

車・バイク

[カー用品] [カーナビ] [カーオーディオ] [タイヤ・ホイール] [洗車用品] [バイク]

ゴルフ

[ゴルフ・クラブ] [ゴルフ・シューズ] [ゴルフ・ウェア] [ゴルフ・バッグ] [ゴルフ・ボール] [ゴルフ・小物] [ゴルフ・トレーニング用具]