[No.40 Len関数で遊ぶ、遊ばれる] [No.41 AccessのForm .Pictureプロパティで画像参照] [No.42 ExcelのFormとシートを連動させる] [No.43 セルのB3を参照するには?] [No.44 Cells(257)とCells(2,1)の関係] |
||
No.40 | 2003/01/04 Len関数で遊ぶ、遊ばれる |
[ページTOPへ戻る] |
<Len関数で遊ぶ、遊ばれる>
こんにちは、三流プログラマーKen3です。 今回は、 Len関数で遊ぶ、遊ばれる です。 気楽に読んでください。 /* * 1.文字列を囲う処理で、問題あり */ 下記のような ┌──────────┐ │文字列を囲ってみたい│ └──────────┘ なんて、文字列を作る処理の説明を [No.34 ┌ ─ ┐│└ ┘を使って、文字列を囲ってみたい] でやりました。覚えてますか? で、問題があって、 ^^^^^^^^^^^^^^^^^^ 半角のABCを入れると ┌───────────┐ │半角のABCを入れると│ └───────────┘ と変換されてしまいます。 原因が、半角文字なので、 前回の[No.39 StrConv関数で半角を全角文字にしてみた] では、安易にStrConv関数を使用して、半角文字を全角文字に強制的に直しました。 こんな修正してると、読者離れを起すと危機感(ホントか?)を持った三流作者が 今回、Len関数と格闘して?修正してみたいと思います。 /* * 2.Len関数の単体テスト */ 文字数を数えるLen関数かぁ、ここで半角文字をうまく処理したいなぁ。 VBAの編集画面で、CTRL+Gを押して、 イミディエイト ウインドウ(舌かんだ、じゃなくって指ツッタ)を表示させて、 軽く関数のテストをするか。 (イミディエイトの説明は--> http://www.ken3.org/vba/iwind.html 参照) a = "VBAで楽しく" ? a VBAで楽しく ? len(a) 7 あれ?7が返ってくるね。(Len関数は文字数を返すから普通だろ驚くなよ) ヘルプ見ると、 指定した文字列の文字数または指定した変数に必要なバイト数 を表す長整数型 (Long) の値を返します。 う〜ん、、、あっ、ヘルプのメモを見ると メモ 文字列をバイト データとして扱う場合は、LenB 関数を使用します。 LenB 関数は、指定した文字列のバイト数を返します。 おっ、このLenBって使えそうですね。 ? lenb(a) 14 なんだよ、 思った数値半角の3文字(VBA)と全角の4文字(で楽しく) で11(3+8で)ってだしてよ。。。 そのままじゃ使えないんだよね。 何でだよコラ。オイ黙ってないで答えろよ、 偉そうにしやがって。 ~~~~~~~~~~~~~~~~~~ VBA Len関数で得意のhttp://www.google.co.jp/で検索すると、 すぐに役立つエクセルVBAマクロ集 FAQ ... http://www.asahi-net.or.jp/~zn3y-ngi/YNxv9872.html これにズハリ回答が載ってるよね。 ユニコードかぁVBAと半角でも6ってことか、 LenBを使う前に、UniCodeから戻してから数えるために、 StrConv関数を使ってと、 変換モードにvbFromUnicodeってあるので、 (文字列を Unicode からシステムの既定のコード ページに変換) ? LenB(StrConv("VBAで楽しく", vbFromUnicode)) 11 おっ、これでなんとかなりそうですね。 /* * 3.関数の単体確認が終わったので組みこむ */ やっと、単体の確認が終わったので、組み込みますか。 ? LenB(StrConv("VBAで楽しく", vbFromUnicode)) 11 と半角換算した数が求められるから、 修正点としては、 ・全角の横棒を引いてるループカウンタの修正 ・"VBAで楽しく"みたいに半角文字が奇数だったら"VBAで楽しく "とスペース調整 ですね。 Private Sub btnCONV_Click() Dim i As Integer Dim strLINE1 As String '1行目 Dim strLINE2 As String '2行目 Dim strLINE3 As String '3行目 Dim nBCNT As Integer '文字列の半角換算数 vba040で追加 'vba040で半角文字を想定して追加 nBCNT = LenB(StrConv(txtMOTO, vbFromUnicode)) 'バイト数を計算 If (nBCNT Mod 2) = 1 Then 'Mod演算子で2で割った余りが1か判断 txtMOTO = txtMOTO & " " 'スペースを1つ追加 nBCNT = nBCNT + 1 '文字数も増やす End If '1行目を作る strLINE1 = "┌" '初めに左上端を代入 For i = 1 To nBCNT / 2 '全角─なのでバイト数/2をカウンタ strLINE1 = strLINE1 & "─" Next i strLINE1 = strLINE1 & "┐" '右上端を付ける '2行目を作る strLINE2 = "│" & txtMOTO & "│" '両端に│を付ける '3行目を作る strLINE3 = "└" '初めに左下端を代入 For i = 1 To nBCNT / 2 '全角─なのでバイト数/2をカウンタ strLINE3 = strLINE3 & "─" Next i strLINE3 = strLINE3 & "┘" '右下端を付ける '結果の代入 各ラインをvbCrLFでつなげただけ txtSAKI = strLINE1 & vbCrLf & strLINE2 & vbCrLf & strLINE3 End Sub こんな感じで修正しました。 ポイントは、 ^^^^^^^^^^^ Dim nBCNT As Integer '文字列の半角換算数 vba040で追加 カウンターの変数を追加して、 'vba040で半角文字を想定して追加 nBCNT = LenB(StrConv(txtMOTO, vbFromUnicode)) 'バイト数を計算 テキストボックスtxtMOTOの半角換算したバイト数を計算して、 If (nBCNT Mod 2) = 1 Then 'Mod演算子で2で割った余りが1か判断 txtMOTO = txtMOTO & " " 'スペースを1つ追加 nBCNT = nBCNT + 1 '文字数も増やす End If MOD演算子で、2で割った余りが1か?奇数か?と判断し、 奇数だったら、半角スペースを+して(横棒が全角なので) 忘れないで文字数も増やします。 For i = 1 To nBCNT / 2 '全角─なのでバイト数/2をカウンタ は、 nBCNTは半角換算の数なので、/2で調整してます。 こんな感じで修正しました。 一番のポイントは、関数の単体テストでクリアした、 nBCNT = LenB(StrConv(txtMOTO, vbFromUnicode)) 'バイト数を計算 ですね。 /* * 4.おわりの挨拶 */ 今回は、長くヒッパッタケド、 ・LenB(StrConv(txtMOTO, vbFromUnicode)) の一言かなぁ。 ネットで検索しただけって説もあるけどね。。。ギク。。。 サンプルファイルは、 http://www.ken3.org/vba/lzh/vba040.lzh に test040-book.xlsが保存されています。 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。
No.41 | 2003/01/07 AccessのForm .Pictureプロパティで画像参照 |
[ページTOPへ戻る] |
<AccessのForm .Pictureプロパティで画像参照>
こんにちは、三流プログラマーKen3です。 今回は、 Access Form .Pictureプロパティ です。 気楽に読んでください。 /* * 1.問合せメールで意外と多いのが */ 問合せメールで意外と多いのが、 1999/12/05に愚痴系のメルマガで作成した、 Access97 画像リンク処理(埋め込みでMDB肥大を防止?) http://www.ken3.org/backno/backno_guchi06.html#28 http://www.ken3.org/backno/hosoku/028/index.html ←画像付き と <Access97 Pictureプロパティ> http://www.ken3.org/backno/hosoku/e010/index.html の Accessで画像関係の処理です。 /* * 2.仕様を考える */ CD−RやDVD〜が普及してるから、 画像はMDBとは別のエリアにあると仮定して、 設定テーブルを作って、画像保存ディレクトリを管理するか。 で、データファイルには、画像のファイル名を入力して、 画像保存ディレクトリ+画像ファイルで処理するかな。 う〜ん、いつもながら、アバウトな仕様だね(適当?) /* * 3.保存ディレクトリの管理 */ 保存ディレクトリの管理どうしようかなぁ、 DNAじゃなくて、レジストリに書くなんてカッコイイことしなくてイイヤ。 (オイオイ、だったら、レジストリなんて単語書くなよ、混乱するだろ) テーブルを1つ作ります。 名前は、保存場所でイイヤ。 で、中身のフィールドは、GPATHでいっかな。 テーブルの新規作成 ^^^^^^^^^^^^^^^^^^ GPATHとフィールド名を入力、 保存ボタンを押してと、 テーブル名を聞いてくるから、保存場所にしてと。 何?主キー?が設定されてない?勝手にやれよとOKを押す。 メニュー兼画像ディレクトリ入力のフォームを作成 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 簡単に画面を作る方法を1つ(ウイザードの紹介だけどね) フォームの新規作成を押します。 フォームウィザードとテーブルを選択します(テーブルは先ほど作った保存場所) 表示したいフィールドを聞いてくるので、 GPATHを選択してます(IDは、使わないのでほっときましょう) 次へを押してと、 すると、フォームの表示形式を聞いてくるので、 単票を選択します。 次は画面スタイルかぁ、まぁ何でもいいんだけど無難な標準で。 最後に保存名称を聞かれるので、メニューと入れました。 完了(完成しました) うわ、小さい(笑) デザインモードで、変更するから、いっか。 落ち着いて、閉めてと。 空のデータを1行作る ^^^^^^^^^^^^^^^^^^^^ フォームを修正する前に、テーブルに空のデータを入れておきます。 まぁ理由は今は気にしないで、空データとでも入れて下さい。 (たいした理由じゃないけど) フォームの修正 ^^^^^^^^^^^^^^ 大枠は、ウィザードで作ってもらったから、フォームを変更します。 ここでのポイントは、 ・更新オンリーにする(追加、削除をいいえの禁止にする) ・レコードセレクタを消す かなぁ まず、更新オンリーにするには、 フォームのプロパティのデータを選択して、 削除の許可をいいえ 追加の許可をいいえ にします。 えっ、何で更新のみにするかって? 設定レコードを消されるのがイヤ(削除の禁止)、 レコードを増やされるとどっちをみるかわからないので(追加の禁止) してます。 早い話、設定用のテーブルなので1つのレコードが必要なので。 次は、見た目の問題なんだけど、 レコードセレクタと移動ボタンを消します まぁ、あってもいいんだけど(笑) あとは、ラベルを画像保存場所とか修正して、 タイトルも入れとくか。 /* * 4.こっちが本題、画像付きのフォームを作成 */ なんか、マスター画面作りで疲れてしまった。 フォーム作り講座とわかり易く分けろよな、まったく三流作者は。 例題は、読者の皆さんもお疲れだと思うので、軽く。 テーブルの作成 ^^^^^^^^^^^^^^ データは、テーブル名を安易に画像リスト フィールドは、 ID オートナンバー型 F_TITLE テキスト型 画像のタイトルを入れます F_GFILENAME テキスト型 画像ファイル名(001.jpgとフォルダー抜きのファイル名) F_MEMO メモ型 コメントなど にします。 フォームを作成 ^^^^^^^^^^^^^^ テーブルを作ったら、ウィザードで単票フォームでも作るか。 大枠を作ってもらったから、細部を追加しないとね。 デザインの編集モードにしてと 非連結のイメージ ^^^^^^^^^^^^^^^^ コントロールのイメージを選択、 表示エリアを作成します。 イメージを選べって言ってくるので、適当に選びます。 プロパティのピクチャタイプを 埋めこみ から リンクに直します。 次に、適当に選んだファイル名を削除します。 すると、背景のグラフィックを消すか?としつこく確認来るので、 うるせぇとつぶやきながら「はい」を選択します。 ↑独り言はまわりに迷惑だし、さびしいのでやめましょう(笑) オブジェクトの名前、イメージ10とかだと、イヤなので、 画像とかオブジェクトの名前を変えます (今回は、名前の規則守ってないけど、規則を作ったほうがいいですよ) やっと、フォームも完成しましたね。 よし、実行。あれ?ファイル名入れても画像表示されないよ。 笑わせないでよ(笑) だって、処理を書いてないでしょ、処理を。 フォーム作っただけで、思ったように動いたら苦労しないって。 動的に画像を入れかえるプロパティを探る ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ プロパティには、 値の取得のみ可能、値の取得および設定ともに可能 と2パターンあります。 なんて説明を、 http://www.ken3.org/backno/backno_vba08.html#36 [No.36 オブジェクトのプロパティについて] プロパティを調べる方法は、 http://www.ken3.org/vba/excel-help.html で いろいろと書いてたけど、 フォームのエディターって便利だよね、 だって、オブジェクト(コントロールなど)選択すると、 プロパティが表示されてるので、 知りたいプロパティの場所でF1(ヘルプ)を押すと、 簡単にヘルプが表示される。 ピクチャーの部分でF1(ヘルプ)を押すと、 グラフィックスのパスと名前を含む文字列式を、次の例のように使うことができます。 btnShowLogo.Picture = "c:\Windows\Winlogo.bmp" と書いてあります。 なるほどね、 .Picture = "画像ファイル名の文字列" で、できそうですね。 イベントを探る ^^^^^^^^^^^^^^ やりたいことは、 .Picture = "画像ファイル名の文字列" あとは、処理を入れるタイミングかぁ。 イベント処理については、 http://www.ken3.org/backno/backno_vba08.html#35 で軽く書いてたけど、 フォームのエディターって便利だよね(またかよ) オブジェクトを選択すると、あれ発生するイベントが書いてある。 私が今やりたいのは、 ・画像ファイル名が入力されたら、画像を表示。 ・次のレコードや前のレコードにデータが移動されたら の2つのタイミングで、画像を表示したいので、イベントを探る。 テキストボックスをクリックして、イベントを見る。 更新後処理ってのが怪しそうなので、そこでF1(ヘルプ)を押す。 BeforeUpdate、AfterUpdate イベント AfterUpdate コントロールまたはレコードで変更されたデータが更新された直後に発生します。 よし、まず1つは、テキストボックスのAfterUpdate イベント 次は、次のレコードや前のレコードにデータが移動されたらのイベントを探るか。 フォームを選択して、イベントを見る。 おっ、レコード移動時って見たまんまがあるよ、これ使ってみるか。 コードを書く ^^^^^^^^^^^^ ここまで来て、やっとコードを書けるよ(長かった) コードを記述するには、レコード移動時を選択すると右側にある..を押すと、 ビルダが出てくるので、コードを選択が一番簡単かなぁ。 Private Sub Form_Current() End Sub と表示されるので、ここに、 オブジェクト.Picture = "画像ファイル名の文字列" を書けばいいのかぁ。 画像のファイル名は、 メニュー画面で作った、設定のGPATH と フォーム内の画像ファイル名を入れるF_GFILENAME を足したものだから、 私はあまり使わないけど右クリックのビルドを選択すると、 オブジェクトの一覧がでます。 全てのフォームからForms![メニュー]![GPATH] 読み込まれたフォームから、Me![F_GFILENAME] と探すことも出来ます(これは、また補足で発行数稼ぐのでその時にでも) Private Sub Form_Current() Dim strFNAME As String '画像ファイル名 'ファイル名フルパスを作成 strFNAME = Forms![メニュー]![GPATH] & Me![F_GFILENAME] End Sub ファイル名が作成できたら、何しよう? あっ、そのファイルが存在するか、いつものDir関数でチェックかな。 その後、.Picture にセットかな。 Private Sub Form_Current() Dim strFNAME As String '画像ファイル名 'ファイル名入力済みかチェック(新規、未入力、クリアを考慮する) If Len(Me![F_GFILENAME] & "") = 0 Then Me![画像].Picture = "" Exit Sub 'ここから後ろは処理しないので抜ける End If 'ファイル名フルパスを作成 strFNAME = Forms![メニュー]![GPATH] & Me![F_GFILENAME] 'ファイルの存在をチェックする If Dir(strFNAME) = "" Then Me![画像].Picture = "" 'ファイルが見つからないので画像は無しにする Else Me![画像].Picture = strFNAME '画像ファイル名をセットする End If End Sub 同じのコピーして、テキストボックスの更新後にも入れてと、 Private Sub F_GFILENAME_AfterUpdate() Dim strFNAME As String '画像ファイル名 Me![F_GFILENAME] = Trim(Me![F_GFILENAME]) 'スペースを取り除く 'ファイル名入力済みかチェック(新規、未入力、クリアを考慮する) If Len(Me![F_GFILENAME] & "") = 0 Then Me![画像].Picture = "" Exit Sub 'ここから後ろは処理しないので抜ける End If 'ファイル名フルパスを作成 strFNAME = Forms![メニュー]![GPATH] & Me![F_GFILENAME] 'ファイルの存在をチェックする If Dir(strFNAME) = "" Then Me![画像].Picture = "" 'ファイルが見つからないので画像は無しにする MsgBox strFNAME & "は、見つかりません" Else Me![画像].Picture = strFNAME '画像ファイル名をセットする End If End Sub 違いは、入力したファイルが無い時は、メッセージを表示したぐらいかなぁ。 *レコード移動時に出ると、うざったいので。 Forms![メニュー]![GPATH] を 参照しているので、 テストの時、メニューが立ち上がってないとエラーが発生します。 マスター管理は違う方法のほうがいいのかも。 これも別の機会に。 /* * 5.おわりの挨拶 */ 今回は、 ・Accessフォームをウィザードで作る ・.Pictureで画像の管理 でした。 サンプルファイルは、 http://www.ken3.org/vba/lzh/vba041.lzh に db041.mdb(Access97で作成)が保存されています。 .jpgや.bmpを指定して、遊んでみてください。 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。
No.42 | 2003/01/09 ExcelのForm シートと連動させる |
[ページTOPへ戻る] |
<ExcelのForm シートと連動させる>
こんにちは、三流プログラマーKen3です。 今回は、 ExcelのFormで少し遊んでみます。 中身は単純に、移動のボタンを作ってデータ読み書きしただけです。 気楽に読んでください。 /* * 1.Accessの入力フォームが簡単な理由 */ Accessでフォーム作るのって意外と簡単ですよね。 入力フォーム作る時、 テーブルやクエリーのデータと連動させるので、 簡単にそれなりの入力フォームを作ることが出来ると思います。 あと、ウィザードがあって、テーブルから半自動的にフォームを生成してくれたり。 まぁ、変なことばっかり言ってると、 Excelユーザーに嫌われるので、 今回は軽くExcelでデータ確認のフォームを作ってみます。 /* * 2.前回の自分と対決するか(笑)仕様を考える */ 前回、 In message "[VBAで楽しく No.041] - AccessのForm .Pictureプロパティで画像参照", >テーブルの作成 >^^^^^^^^^^^^^^ >データは、テーブル名を安易に画像リスト >フィールドは、 >ID オートナンバー型 >F_TITLE テキスト型 画像のタイトルを入れます >F_GFILENAME テキスト型 画像ファイル名(001.jpgとフォルダー抜きのファイル名) >F_MEMO メモ型 コメントなど >にします。 --- とAccessのテーブルで管理してたっけ、 こいつを、 シート名をDATA 1行目は見出しの行にして、 2行目から、 A列 画像タイトル B列 画像ファイル名 C列 コメント でデータを簡単にシートで管理しますか。 あっ、忘れてた、画像の保存してあるベースのディレクトリも管理してたっけ、 これは、DATA!E1に入れとけばイイヤ。 シートのイメージは _____A_____________B_________C____________D_______________________E_______ 1 画像タイトル ファイル名 コメント 画像ベースディレクトリ→ D:\temp\ 2 サンタ 001.gif ケーキ写真 3 お正月 012.jpg XXXXXXXXXX 4 といった感じにします。 /* * 3.Excelのユーザーフォームを作成する */ 軽く下記のような部品を使いました。 (フォームに貼ったコントロールの一覧です) タイトル ___________ txtTITLE ファイル名 ___________ txtFILENAME コメント ___________ txtMEMO ┌────┐ │前へ戻る│btnPREV └────┘ ┌───┐ │ 次へ │ btnNEXT └───┘ ┌────┐ │ │imgBOX(イメージコントロール) └────┘ を作成しました。 Excelフォームの作成サンプルは http://www.ken3.org/vba/excel-form.html に軽くまとめてあるので、見てください。 が作成した画像です。 美的センスの無さを痛感しつつ、中身で勝負にもってくか (フォーム作りや色使い、うまい人いますよね、正直うらやましいです) /* * 4.中身で勝負?コードを書き込む */ 部品を貼れたので、コードを書きます。 外見がイマイチなので、中身はまともにいきたいですよね(冗談です) VBAのプログラムは、 イベント(タイミング)を考えながらやると、 わかり易いと思います。 考えられるタイミングは、 移動の2つのボタンを押した時の処理ですね。 ┌────┐ │前へ戻る│btnPREV は、前のデータを表示 └────┘ ┌───┐ │ 次へ │ btnNEXTは、次のデータを表示 └───┘ とすると、現在表示されている行を何かで取っておかないといけないか。 *グローバル変数の使い方、説明してないけど今回、使っちゃいます。 テキストボックスでデータが変更されたらシートの値も変えないとなぁ。 それと、フォームを開いた時に初期データを表示しないとね。 フォームを開いた時、 ^^^^^^^^^^^^^^^^^^^ データ(2行目の初期データ)をまず表示したいので、 プログラムを書いてみたいと思います。 SubやFunctionの外に変数を宣言すると、 共通に使えるので、行カウンタの意味を込めて変数yCNTを作成します。 Dim yCNT As Integer '行カウンター 次にフォームを開いた時のイベントを書きます Private Sub UserForm_Initialize() End Sub _Initializeが該当イベントなので、 この中でやることは、 カウンターの初期値を2(行目)にする。*タイトルが1行目なので タイトル [ ___________ ] txtTITLE ファイル名 [ ___________ ] txtFILENAME コメント [ ___________ ] txtMEMO のテキストボックスにシートの値(セルの値)を代入する と 同時に、画像ファイルを表示 の大きく分けると3つかぁ。 Private Sub UserForm_Initialize() Dim strFNAME As String 'ファイル名作成用 '初期処理 yCNT = 2 '初期値の2行目を代入 'セルの値をフォームのテキストボックスに代入する txtTITLE = Sheets("DATA").Cells(yCNT, "A") txtFILENAME = Sheets("DATA").Cells(yCNT, "B") txtMEMO = Sheets("DATA").Cells(yCNT, "C") '画像ファイルを表示する If Trim(txtFILENAME) = "" Then 'ファイル名が入力されているかチェック imgBOX.Picture = LoadPicture("") '画像を消す Exit Sub End If strFNAME = Sheets("DATA").Range("E1") & txtFILENAME 'ファイル名を作成 If Dir(strFNAME) = "" Then 'ファイルが存在するかチェック '存在していない時 imgBOX.Picture = LoadPicture("") '画像を消す Else imgBOX.Picture = LoadPicture(strFNAME) 'ファイル名をセット End If End Sub 初期処理 ~~~~~~~~ yCNT = 2 '初期値の2行目を代入 もう見たまんまですよね。 2行目の2を代入してます。 セルの値をフォームのテキストボックスに代入する ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ txtTITLE = Sheets("DATA").Cells(yCNT, "A") txtFILENAME = Sheets("DATA").Cells(yCNT, "B") txtMEMO = Sheets("DATA").Cells(yCNT, "C") これもそのまま代入してます。 あっ、Sheets("DATA").Cells(yCNT, "A")の説明もして無いや。。。 イメージはわかると思うので今回はやらないけど、 近いうちにSheetsオブジェクト、Cellsオブジェクト説明します。 画像ファイルを表示する ~~~~~~~~~~~~~~~~~~~~~~ If Trim(txtFILENAME) = "" Then 'ファイル名が入力されているかチェック imgBOX.Picture = LoadPicture("") '画像を消す Exit Sub End If ファイル名が入力されている時だけ処理したいので、 入力されていない場合は、 imgBOX.Picture = LoadPicture("") '画像を消す と画像を消してから、関数をExit Subで途中バックレしてます。 strFNAME = Sheets("DATA").Range("E1") & txtFILENAME 'ファイル名を作成 ここは、ファイル名のフルパスを作成してて、 DATA!E1のセルに基本のディレクトリが入っているので、 それと、テキストボックスのファイル名を&で連結してます。 If Dir(strFNAME) = "" Then 'ファイルが存在するかチェック '存在していない時 imgBOX.Picture = LoadPicture("") '画像を消す Else imgBOX.Picture = LoadPicture(strFNAME) 'ファイル名をセット End If お約束のDir関数でファイルの存在をチェックして、 ””のファイル無しの時は、 imgBOX.Picture = LoadPicture("") と画像を消して、在りの時は、 imgBOX.Picture = LoadPicture(strFNAME) で、画像をセットしてます。 注).Picture の使い方がAccessと違って、LoadPicture関数の戻り値をセットです。 前、次のボタンが押された時 ^^^^^^^^^^^^^^^^^^^^^^^^^^ イベントのタイミングであるのが、 前、次のボタンが押された時ですよね。 普通に考えて、 前のボタンが押されたら、カウンタのyCNT−1 次のボタンが押されたら、カウンタのyCNT+1 ですよね。 その後、データセットと画像表示です。 ┌────┐ │前へ戻る│btnPREV は、前のデータを表示 └────┘ ┌───┐ │ 次へ │ btnNEXTは、次のデータを表示 └───┘ の_Clickイベントにコードを書きます Private Sub btnNEXT_Click() Dim strFNAME As String 'ファイル名作成用 '次の位置を計算 yCNT = yCNT + 1 '行カウンタを増やす 'セルの値をフォームのテキストボックスに代入する txtTITLE = Sheets("DATA").Cells(yCNT, "A") txtFILENAME = Sheets("DATA").Cells(yCNT, "B") txtMEMO = Sheets("DATA").Cells(yCNT, "C") '画像ファイルを表示する If Trim(txtFILENAME) = "" Then 'ファイル名が入力されているかチェック imgBOX.Picture = LoadPicture("") '画像を消す Exit Sub End If strFNAME = Sheets("DATA").Range("E1") & txtFILENAME 'ファイル名を作成 If Dir(strFNAME) = "" Then 'ファイルが存在するかチェック '存在していない時 imgBOX.Picture = LoadPicture("") '画像を消す Else imgBOX.Picture = LoadPicture(strFNAME) 'ファイル名をセット End If End Sub Private Sub btnPREV_Click() Dim strFNAME As String 'ファイル名作成用 '前の位置を計算 yCNT = yCNT - 1 '行カウンタを減らす 'セルの値をフォームのテキストボックスに代入する txtTITLE = Sheets("DATA").Cells(yCNT, "A") txtFILENAME = Sheets("DATA").Cells(yCNT, "B") txtMEMO = Sheets("DATA").Cells(yCNT, "C") '画像ファイルを表示する If Trim(txtFILENAME) = "" Then 'ファイル名が入力されているかチェック imgBOX.Picture = LoadPicture("") '画像を消す Exit Sub End If strFNAME = Sheets("DATA").Range("E1") & txtFILENAME 'ファイル名を作成 If Dir(strFNAME) = "" Then 'ファイルが存在するかチェック '存在していない時 imgBOX.Picture = LoadPicture("") '画像を消す Else imgBOX.Picture = LoadPicture(strFNAME) 'ファイル名をセット End If End Sub ポイントは、 yCNT = yCNT + 1 '行カウンタを増やす yCNT = yCNT - 1 '行カウンタを減らす の増減です。 カウンターを移動させて、代入位置を変化させて対応してます。 ね、なんとか動作したでしょ。 なんかオレ、頭イタクなってきた。 なんで? よくそんな同じ処理をダラダラ書けるよね。 カウンターの意味わかってないんじゃないの? *関数にまとめるのも次回かなぁ(先送りが多いよねこのメルマガ(笑)) テキストボックス入力後、シートに値をセットする ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 初期処理、前・次移動のボタンができたから、 次は、テキストボックスでデータが修正された時だよね。 タイトル [___________] txtTITLE A列 ファイル名 [___________] txtFILENAME B列 コメント [___________] txtMEMO C列 だから、それぞれ、_Changeのイベントで Private Sub txtMEMO_Change() 'テキストボックスの値をシートへ代入 Sheets("DATA").Cells(yCNT, "C") = txtMEMO End Sub Private Sub txtTITLE_Change() 'テキストボックスの値をシートへ代入 Sheets("DATA").Cells(yCNT, "A") = txtTITLE End Sub 値を普通に代入。 ファイル名は変わったら、画像も変えなきゃいけないので、 Private Sub txtFILENAME_Change() 'テキストボックスの値をシートへ代入 Sheets("DATA").Cells(yCNT, "B") = txtFILENAME '画像ファイル名が変更されたので、画像の処理を行う If Trim(txtFILENAME) = "" Then 'ファイル名が入力されているかチェック imgBOX.Picture = LoadPicture("") '画像を消す Exit Sub End If strFNAME = Sheets("DATA").Range("E1") & txtFILENAME 'ファイル名を作成 If Dir(strFNAME) = "" Then 'ファイルが存在するかチェック '存在していない時 imgBOX.Picture = LoadPicture("") '画像を消す Else imgBOX.Picture = LoadPicture(strFNAME) 'ファイル名をセット End If End Sub と画像の表示処理を追加してと、OKできたぁ。 OKできたぁ。じゃねぇよ。 ここでも画像の同じ処理書くの? えっ、だって、画像のファイル名が変わったから、同じ処理しなきゃ。 う〜ん、ダメか今日は。。。(同じ処理をまとめるのは次かなぁ、、まったく) /* * 5.おわりの挨拶 */ 今回は、 ・Excelフォームとシートのデータを連動させてみた ・注).Picture の使い方がAccessと違って、LoadPicture関数の戻り値をセット でした。 残は、多くって ・グローバル変数って何? ・シート!セルの値の表現方法 ・同じ処理をまとめるには? ・前のボタンを押しつづけるとエラー(そんなの本文で一言も書いてないよ) ・次のボタンを最終データ以降も押せる(そんなの本文で一言もフレテナイよ) 書きたくないほどいっぱいの課題アリ(笑) サンプルファイルは、 http://www.ken3.org/vba/lzh/vba042.lzh に test042-book.xlsが保存されています。 .jpgや.gifを指定して、遊んでみてください。 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。
No.43 | 2003/01/10 セルのB3を参照するには? |
[ページTOPへ戻る] |
<セルのB3を参照するには?>
こんにちは、三流プログラマーKen3です。 今回は、 ExcelのCellsで少し遊んでみます。 気楽に読んでください。 /* * 1.基本のSheets("シート名").Cells(y行, x列) */ ExcelのセルB3に対して、値をセットするには、 得意のマクロ記録を使うと、 Sub Macro1() Range("B3").Select ActiveCell.FormulaR1C1 = "abc" Range("B4").Select End Sub と記録されます。 Range("B3").Selectして、ActiveCell.FormulaR1C1 = "abc"で代入 やってることわかるんだけど何かなぁ。 マクロ記録は操作の記録なので、 B3を選択、現在のセルに値を入力 とそのまま純粋に動いてます。 セルの選択はいらないから、値を代入したいなんて時は、 Sheets("シート名").Cells(y行, x列) とコードを記述します。 Sub test043_1() Dim strDATA As String strDATA = InputBox("B3に入れるデータは?") '入力する Sheets("Sheet1").Cells(3, 2) = strDATA End Sub ねっ、簡単でしょ。 シート名を指定して、.Cells(3, 2)とやってるだけです。 B3は、3行目、2列目なので、3,2とパラメータを渡しています。 シートのオブジェクトを省略して、 Cells(3, 2) = strDATA と書いたりもできます。 (ActiveSheet.Cells(3, 2)と現在選択されてるシートって書き方もあります) VBAで配列変数を宣言して使ってましたが、 Excelのセルも2次元の大きな変数だ、、、 なんて思うとCells(3, 2)もわかりやすいかなぁ。 大きな変数かぁ、、、 http://www.ken3.org/vba/iwind.html の <イミディエイト ウインドウ と Debug.Print> で Sub aaa() Dim i As Integer Debug.Print "これは?どこに表示されるの?" For i = 1 To 5 Debug.Print i Next i End Sub とやると、値の確認が楽だよって説明してたけど、 ある場所を決めてデータをセルに書き込むと、 簡単なテストの時、便利かもとフト思った。 Sub aaa() Dim i As Integer 'ループのテスト For i = 1 To 5 Cells(3, 2) = i MsgBox "" Next i End Sub あっ、でも、msgboxで止めるんだったら意味無いか。 /* * 2.Cells(nYLINE, "A") 、 A 列って書けるみたい */ まぁ、ここからは余談で、 最近気がついたことを書きます。 *人様のソースを見て、これは?使えるのでは? と思った、ものを今回載せます。 内容は、 セルの選択や参照などで、 私、今まで、Cells(y, x)みたいな使い方しかしていなく、 A列の時は、 ^^^^ Dim nYLINE As Integer For nYLINE = 5 To 200 If Cells(nYLINE, 1) = "対前年比較合計" Then ^^^^^ みたいにしていたのですが、 If Cells(nYLINE, "A") = "対前年比較合計" Then ^^^^^ って書けるんですね。 B3とかだと、3行、Bは2だからCells(3,2)とできるけど、 AC3とか言われると、えっとZが26だから、29か(笑) とアルファベット表記を頭で変換するのってイヤですよね。 Cells(3, "AC")て書けば、使えてしまうんですよ。 Sub test043_2() Dim strDATA As String strDATA = InputBox("B3に入れるデータは?") '入力する Sheets("Sheet1").Cells(3, "B") = strDATA '"B"と指定した End Sub .Cells(3, "B") なんて書けたんですね、不思議だぁ、、、 得意になって書いたけど、みんな知ってたりして。 前回の、 In message "[VBAで楽しく No.042] - ExcelのForm シートと連動させる", > 'セルの値をフォームのテキストボックスに代入する > txtTITLE = Sheets("DATA").Cells(yCNT, "A") > txtFILENAME = Sheets("DATA").Cells(yCNT, "B") > txtMEMO = Sheets("DATA").Cells(yCNT, "C") で、行をカウンター変数にしてデータを操作してました。 こんな書き方もあるんだなぁ、、、程度でOKだと思います。 /* * 3.蛇足Cells(514) = "XXXXX" */ 2次元配列の管理とか、コンピュータのアドレス管理に強い人は、 なんとも感じないかもしれないけど、 ダマされたと思って、下記のコードを Excel VBAで実行してください(Excel 97で確認しました) Sub test043_3() Cells(257) = "257って?A2" Cells(5) = "5?E1" Cells(514) = "514?B3" End Sub Cells(行,列)だから Cells(3,2)など数値で書いてました。 チョット前、 Cells(3, "B") = "ABC" と書くと(B列を自分で2と置き換えないでOK) を発見して、へぇ〜と感動。 で、今は、未知との遭遇で、 Cells(514) = "XXXXX" と書ける?ことを発見。 *あまり使えそうに無いけど、、、 これは、チョットムダな知識だったね、使用方法の例題が思いつかない。。。 Cells(3, "B") = "ABC" は、書き方によっては使えると思うので、覚えておいてください。 あっ、基本形の、Sheets("シート名").Cells(行,列)は、忘れないで。 /* * 4.おわりの挨拶 */ 今回は、 ・Sheets("シート名").Cells(行,列)の基本形 ・Cells(3, "B")って書き方も可能です ・蛇足Cells(514) = "XXXXX" でした。 サンプルファイルは、 http://www.ken3.org/vba/lzh/vba043.lzh に test043-book.xlsが保存されています。 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。
No.44 | 2003/01/12 Cells(257)とCells(2,1)の関係 |
[ページTOPへ戻る] |
<Cells(257)とCells(2,1)の関係>
こんにちは、三流プログラマーKen3です。 今回は、質問メールもらったので、 Cells(257)とCells(2,1)の関係 を少し書きます。 気楽に読んでください。 /* * 1.質問内容 */ 下記の質問メールもらいました。 --- In message "セルのB3を参照についての質問", garakutaさん wrote... >突然のメール、失礼いたします。 > > VBAで楽しく No.043で > Cells(257) = "257って?A2" > Cells(5) = "5?E1" > Cells(514) = "514?B3" >という記述がありました。 > ()内の数と(2,1)等の関係がわかりませんでした。 >行番号、列番号からどのように計算しているのでしょうか? --- ホントは、質問の処理も先入れ先出し(先に来た質問を先に答える) のが良いのですが、今回は順番無視して答えやすい質問を答えます。 /* * 2.シートが管理するセルの最大値 */ シートってのは、256列×65536行のセルを持ってて、 それで、A2 A列2行は、257だったんですよ。 と、突然言っても?マークですよね。 まず、データをスクロールさせ、最終のセルを選択します。 Excelのオプションで、参照方式をR1C1形式に変えます。 最後の列IVは256番目の列だったんですね。 それで、256+1の計算式で257だったんです。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ あまり使わない方法なので、 普通にCells(2,1)のほうがわかり易いし、使いやすいと思います。 /* * 3.余談、Range("C2:E10").Cells(2, 2) = "BBB" */ Rangeの説明を近いうちにするのですが、 シートは、256列×65536行のセルを持っていてでしたね。 セルの範囲を指定する方法で、 Rangeオブジェクトってあって、 Sub aaa() Range("C2:E10").Cells(1, 1) = "AAA" Range("C2:E10").Cells(2, 2) = "BBB" End Sub みたいに、C2:E10の範囲よくワークシート関数のSUMとかで使いますよね、 その範囲に対して、.Cells(1, 1) = "AAA"をセットみたいに書けます。 (C2:E10の枠内の行1列1番目みたいなイメージかなぁ。) 表の表示エリアをRange("C2:E10")とか設定しとくと便利かもしれません。 /* * 4.おわりの挨拶 */ 今回は、 ・シートってのは、256列×65536行のセルを持ってます。 ・余談、Range("C2:E10").Cells(2, 2) = "BBB" と書くことも出来ます でした。 Rangeオブジェクトの説明、速めにやらないとなぁ。 何か素朴な疑問などあったら、メール、掲示板に気軽に書いてください。 拾い読みして、 1つでも何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。
目的の情報を探すには、最近はググれとよく聞きます。なので、検索ボックスを付けました。
いろいろなキーワードを入れて、検索してみてください。
ここまで、読んでいただきどうもです。ここから下は、三流君宛のメッセージ送信や 三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、※質問や感想は、気軽に送ってくださいね。
質問や要望など連絡方法でお互い確認が取りやすく、便利なのが掲示板なのですが、私の対応のまずさから不定期で荒れてしまい、掲示板は現在封鎖中です。(反省しなきゃ)
感想や質問・要望・苦情など 三流君へメッセージを送る。 時間的余裕のある要望・質問・苦情の場合は、下記のフォームからメッセージを送ることができます。 |
項目別に↓に人気の記事をまとめてみました。お探しのジャンルを選択してください。
人気記事(来場者が多いTOP3):
[VBAでIE,WebBrowserを操作]・・・VBAでIE,WebBrowserを操作する サンプルです
[Access から Excel 連携 CreateObject("Excel.Application")]・・・AccessからExcelを操作したりデータの書き出しなどです
[VBAでOutlookの操作 CreateObject("Outlook.Application" )]・・・VBAからOutlookを使い、メール関係を処理するサンプルです
↑上記3つみたいなCreateObjectで他のアプリケーションを操作するサンプルが人気です。
開発時の操作: [F1を押してHELPを見る]/ [Debug.Print と イミディエイトウインドウ]/ [実行時エラーでデバッグ]/ [ウォッチ式とSTOP]/ [参照設定を行う]
仕様書(設計書?) XXXX書類: [基本設計書や要求仕様書]/ [テスト仕様書 テストデータ]/ [バグ票]/ [関数仕様書]/ [流れは 入力・処理・出力]
Excel関係:
[Excel UserFormを操作する]・・・エクセルでユーザーフォームを作成して入力などを行ってます
[ExcelからAccessを操作する]・・・ExcelからAccessのマクロを起動してみました、
[Excel関係 関数、その他]・・・その他Excel関係です
Access関係:
[Access UserForm/サブフォーム 操作]・・・アクセスでフォームを使ったサンプルです
[Access レポート操作]・・・レポートを操作してみました
[Access クエリーやその他関数]・・・あまりまとまってませんが、スポット的な単体関数の解説です
その他:VBAの共通関数やテキストファイルの操作など
[VBAでテキストファイル(TextFile)の操作]・・・普通のテキストファイルを使ったサンプルです
[VBA 標準関数関係とその他解説]・・・その他、グダグタ解説してます
Blog:[三流君の作業日記]/
[サンプルコードのゴミ箱]/
広告-[通販人気商品の足跡]