忙しい現代人の腰&肩のお悩み対策!

VBAを使ってシート上の全てのテキストボックスのテキストを取得・出力するマクロを作成したいと思っていますがうまく行きませんので、お知恵を拝借したいと思います。

環境:Windows10 Office2016

状況:
既存のエクセルシートに約100個以上のテキストボックスが作成されており
一覧を作成するためにセルにコピーしたい。

テキストボックスの並び順などは一切こだわりません。
そもそも実現可能かでもご存知の方いらっしゃいましたらお教えください。

質問者からの補足コメント

  • ご指摘いただいた通りオートシェイプです。
    おかげさまで無事プログラムは動作しましたが、1つ疑問があります。

    >Range("A1").Offset(i, 0).Value = tx.Name

     ...
     textbox 130
     textbox 162
     textbox 163

    上記は出力結果の例ですが、数字部分はテキストの作成順を表すものでしょうか。
    そうであれば、例えば新規に追加した図形は textbox 164 となるべきだと思いますが
    実際にはそのようにはなりませんでした。

      補足日時:2017/09/12 16:19

A 回答 (3件)

> 上記は出力結果の例ですが、数字部分はテキストの作成順を表すものでしょうか。


> そうであれば、例えば新規に追加した図形は textbox 164 となるべきだと思いますが

Excelが勝手に付ける番号って以上は、特に決まり無いのでは。
手動でtextbox 165とか、textbox 9999999とか作ったとして、次に連番振らなきゃならないって事もないでしょうし。


> If tx.Type = msoTextBox Then
> のほうが良いかと。

良さげですね。
    • good
    • 0

オートシェイプのテキスト ボックスなら


#1 さんの回答の IF は
If tx.Type = msoTextBox Then
のほうが良いかと。

というか、シートに張り付けられるテキスト ボックスは ActiveX コントロール版のテキスト ボックスもあります。
どちらのテキスト ボックスなのでしょうかね。

ActiveX コントロール版テキスト ボックスの貼り付け方法。
[開発]→[挿入]→[テキスト ボックス (ActiveX コントロール)]

オートシェイプ版テキスト ボックスの貼り付け方法。
[挿入]→[図形]→[テキスト ボックス]
    • good
    • 0

例えば、



Sub ttxtbox()
 Dim tx As Shape
 Dim i As Long
 i = 0

 ' アクティブシートのShape
 For Each tx In ActiveSheet.Shapes
  If tx.AutoShapeType = msoShapeRectangle Then ' オートシェイプの形が四角形?
   Range("A1").Offset(i, 0).Value = tx.Name
   Range("A1").Offset(i, 1).Value = tx.TextFrame.Characters.Caption
   i = i + 1
  End If
 Next
End Sub

だとか。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aと関連する良く見られている質問

Qコピーのvba分かりません

For n = 8 To gyo
If Cells(n, 1) <> "" Then
Cells(6, 1) = ""
Rows("5:6").Select
Selection.Copy
Rows(n, n + 1).Select
Selection.Insert Shift:=xlDown
End If
n = n + 1
Next n
マクロ初心者で、基礎が分かってません。読まれれば、分かられると思いますが、1列目の8行目から行を見ていって、数字が入っていれば、1列目6行目に入っている文字を消して、5、6行目をコピーして、数字の見つかった行とその次の行に5、6行目を挿入コピーし次に行きなさいと書いたつもりですが、Rows(n, n + 1).Selectで動かないように思われます。gyoはgyo = Cells(Rows.Count, 9).End(xlUp).Rowとし、Dim gyo as longと変数宣言してます。nもDim n as longと変数宣言しました。5、6行目には文字の入った結合セルがたくさんあります。Cells(6, 1) = ""は1回すれば良いので、本来はこの位置ではないと思いますが。

For n = 8 To gyo
If Cells(n, 1) <> "" Then
Cells(6, 1) = ""
Rows("5:6").Select
Selection.Copy
Rows(n, n + 1).Select
Selection.Insert Shift:=xlDown
End If
n = n + 1
Next n
マクロ初心者で、基礎が分かってません。読まれれば、分かられると思いますが、1列目の8行目から行を見ていって、数字が入っていれば、1列目6行目に入っている文字を消して、5、6行目をコピーして、数字の見つかった行とその次の行に5、6行目を挿入コピーし次に行きなさいと書いたつもりですが、Rows(n, n + 1)...続きを読む

Aベストアンサー

>Rows("5:6")
これと
>Rows(n, n + 1)
これは、書き方が違っている事はわかりますか?

上は文字列、下は数値になってます。
よって文字列にするため

Rows(n & ":" & n + 1) が同じ書き方になりますね。

でも挿入なら

Rows(n).Select

でいけなかったかな?

QVBA教えてください

以下のようにテキストファイルに記入されている文字列をエクセルに抽出したいのですが
なかなか思うようにいきません。

<テキストデータ>
項 A B C D
1 40
2 30
3 20

<エクセルに抽出したいデータ>
1 40
2 30
3 20


どなたかお詳しい方いらっしゃいましたら教えて頂けると幸いです。

Aベストアンサー

大変遅くなりました。以下のような感じはいかがでしょうか?
---------------------------------------------------------------------------------
Sub Sample()
Dim 対象ファイル As String
Dim 行データ As String
Dim 位置 As Long
Dim 対象位置 As Long
Dim 文字数 As Long
Dim 対象 As Boolean
Dim 行 As Long
Dim 比較文字 As String
Dim 数字 As String
対象ファイル = Application.GetOpenFilename("テキスト ファイル,*.txt")
If 対象ファイル = "False" Then Exit Sub
Open 対象ファイル For Input As #1
Do Until EOF(1)
Line Input #1, 行データ
If 対象 Then
If 対象位置 > Len(行データ) Then 対象 = False
If Mid(行データ, 1, 1) < "0" Then 対象 = False
If Mid(行データ, 1, 1) > "9" Then 対象 = False
If Mid(行データ, 対象位置, 1) < "0" Then 対象 = False
If Mid(行データ, 対象位置, 1) > "9" Then 対象 = False
Else
比較文字 = ""
For 位置 = 1 To Len(行データ)
If Mid(行データ, 位置, 1) <> " " Then
比較文字 = 比較文字 & Mid(行データ, 位置, 1)
If Mid(行データ, 位置, 1) = "D" Then 対象位置 = 位置
End If
Next
End If
If 対象 Then
行 = 行 + 1
数字 = ""
For 位置 = 1 To 対象位置
If Mid(行データ, 位置, 1) < "0" Then Exit For
If Mid(行データ, 位置, 1) > "9" Then Exit For
数字 = 数字 & Mid(行データ, 位置, 1)
Next
Cells(行, 1).Value = 数字
数字 = ""
For 位置 = 対象位置 To Len(行データ)
If Mid(行データ, 位置, 1) < "0" Then Exit For
If Mid(行データ, 位置, 1) > "9" Then Exit For
数字 = 数字 & Mid(行データ, 位置, 1)
Next
Cells(行, 2).Value = 数字
Else
If 比較文字 = "ABCD" Then 対象 = True
For 位置 = 1 To Len(行データ)
If Mid(行データ, 位置, 1) = "D" Then 対象位置 = 位置
Next
End If
Loop
Close #1
End Sub
---------------------------------------------------------------------------------

大変遅くなりました。以下のような感じはいかがでしょうか?
---------------------------------------------------------------------------------
Sub Sample()
Dim 対象ファイル As String
Dim 行データ As String
Dim 位置 As Long
Dim 対象位置 As Long
Dim 文字数 As Long
Dim 対象 As Boolean
Dim 行 As Long
Dim 比較文字 As String
Dim 数字 As String
対象ファイル = Application.GetOpenFilename("テキスト ファイル,*.txt")
If 対象ファイル = "False" Then Exit Sub
Open 対象ファイル For Inp...続きを読む

QVBAのコマンドボタンと入力について

VBA初心者でよくわからないので教えて下さい。
やりたいことは、エクセルシートのA列とかに数個のデータを入力し、コマンドボタンを
押すと入力したデータを取り込んで、処理した値を表示させたいのですが、
UserFormでコマンドボタンを作成し、実行すると、エクセルシートのセルに
入力できなくなってしまいます。
 コマンドボタンを設定しても、通常通り、エクセルシートに入力および編集等ができるように
する方法を教えて下さい。
 また、できないようであれば、コマンドボタン設定以外でなにか方法があれば、
アドバイスお願いします。

Aベストアンサー

>UserFormでコマンドボタンを作成し、実行すると、エクセルシートのセルに入力できなくなってしまいます。

こう言った趣旨のことでしょうか?
UserForm1.Show vbModeless
とすれば、「UserForm1」を表示した状態でもシートの編集は可能になります。
参考
http://www.shoeisha.com/book/hp/pc/office/Excel/files/text2.html


>コマンドボタンを押すと入力したデータを取り込んで、
どこに(どこの値を)取り込みたいのでしょうか?
例えば、UserFormに設定された変数に、sheet1のA1入力(代入)したいのであれば、
UserForm1.変数名=sheets(1).Range("A1")

UserForm1.変数名=sheets(1).cells(1,1)
といったことで可能です。

>処理した値を表示させたいのですが、
こちらは、前述とは逆に
sheets(1).Range("A1")=「処理した値」
とすれば表示(代入)できるはずです。

QVBAでのファイル名と更新日(作成日)の抽出

VBAにてあるフォルダにあるすべてのPDFファイル名と更新日(作成日)の抽出をしたいです。
A1セルに抽出するフォルダパス名が入っています。

A3セルより下(A3,A4,A5~)にファイル名
B3セルより下(B3,B4,B5~)に更新日(作成日)

を表示させたいです。

ご教示願います。

Aベストアンサー

こんばんは。
本日、共有フォルダ(一部無線LANでの中継アリ)でいくつかテストしたのですが直接セルに取得した値を入力していくとかなり遅くなるようですね。

そこで、自分のPCのCドライブ直下に作業用のテキストファイルをつくり、そこにフォルダ内のファイルと更新日時をフィルタリングせずにずらっと書き込み。
それをExcelで、不要ファイルは無視しつつセルに入力していく、、という手法にしてみました。

ここでいう不要ファイルはMacから共有フォルダに書き込んだ際に出来ることがある、”.”で始まる隠しファイルの事です。

ちなみに、820個のファイルがある共有フォルダで、ワークテキスト作成が約20秒、それをExcelのセルに入力するのが「ほんの一瞬」です。
ファイルのなら並びはおそらくファイル名の昇順となっているようですが、そういったソート方法の変更もExcelに読み込んだのちに処理したほうが良いと思います。
ソート範囲の指定は、コードにもありますが、Range("A3", Cells(Cells(Rows.Count, 2).End(xlUp).Row, 2))というようなレコード数によって可変となるようにすれば大丈夫だと思います。

作業用テキストファイルは、該当するファイルが無い場合は新規で作りますし、既存の場合は、前回分はクリアされたうえで書き込まれます。
ファイルの設定場所は自分のPC上で権限ある場所ならどこでも構いません。

また、タブ区切りのテキストしているので、作業用テキストファイルを開いて全選択してコピー、A3セルをクリックした状態でペーストしても(不要ファイル除去を除いては)同じ結果が得られます。

ギリギリ現実な速度かなと思いますが、一度試されてみてください。


----以下 ソース---


Sub Pdflistup()

FolderPath = Range("A1").Value: 'セルA1にフォルダーのパスがあるということなので。
WText = "C:\WorkText.txt": '作業用テキストファイル

'該当フォルダにあるファイルの名称と更新日時を作業用テキストファイルに書き込む

Set FileSys = CreateObject("Scripting.FileSystemObject")
Set FileObj = FileSys.GetFolder(FolderPath).Files
Set WorkText = FileSys.CreateTextFile(WText, True)

For Each PdfObj In FileObj

With PdfObj

WorkText.WriteLine (.Name & Chr(9) & .DateLastModified): '名称(タブ)更新日時の形で書き込み

End With

Next

WorkText.Close

Set FileSys = Nothing

'作業用テキストファイル作成処理完了


'セルの値をクリア(A3~Bの最終行まで)

Range("A3", Cells(Cells(Rows.Count, 2).End(xlUp).Row, 2)).Clear


'WorkText.txtを開き、一行ずつセルに入力(ファイル名はA3から、更新日時はB3から)

Open WText For Input As #1

n = 3: '入力開始行

Do Until EOF(1)

Line Input #1, Tline

Tvalue = Split(Tline, Chr(9)): 'テキストをタブで分割(一次配列格納)

If Not Left(Tvalue(0), 1) = "." Then

Cells(n, 1).Value = Tvalue(0): 'n行A列にファイル名を入力
Cells(n, 2).Value = Tvalue(1): 'n行B列に更新日を入力
n = n + 1
End If
Loop

Close #1


'セル書き込み作業完了

MsgBox ("処理が完了しました。")


End Sub

こんばんは。
本日、共有フォルダ(一部無線LANでの中継アリ)でいくつかテストしたのですが直接セルに取得した値を入力していくとかなり遅くなるようですね。

そこで、自分のPCのCドライブ直下に作業用のテキストファイルをつくり、そこにフォルダ内のファイルと更新日時をフィルタリングせずにずらっと書き込み。
それをExcelで、不要ファイルは無視しつつセルに入力していく、、という手法にしてみました。

ここでいう不要ファイルはMacから共有フォルダに書き込んだ際に出来ることがある、”.”で始まる隠しフ...続きを読む

QVBAで指定シート以外の選択

お世話になっております。
VBAで指定セル以外を選択したいのですがどの様にプログラムを
構成すればよろしいのでしょうか?
全てのシートを選択のプログラムは「Worksheets.Select」ですが
例えばsheet1、sheet2、「勤務表」以外のシートを選択状態にしたいのです。
ご教示をお願い致します。

Aベストアンサー

こんな感じで。

Sub Sample()
  Dim ShName As String
  Dim i As Long
  Dim ara As Variant

  For i = 1 To Sheets.Count
    Select Case Sheets(i).Name
      Case "Sheet1", "Sheet2", "勤務表"
      Case Else
        ShName = ShName & "*" & Sheets(i).Name
    End Select
  Next
  ShName = Mid(ShName, 2)

  If ShName <> "" Then
    ara = Split(ShName, "*")
    Sheets(ara).Select
  Else
    MsgBox "選択できません"
  End If
End Sub

QVBA、マクロについて、どなたか知恵をお貸し願います!

VBA独学中の初心者です。
ある問題に躓いており、どうしても動かない部分があるため、皆様のお力添えをいただきたいです。
説明が稚拙で分かりづらいかもしれませんが、宜しくお願いいたします。

① 2つのbook(book1/book2)があるとし、登録したマクロはbook2に設置する。
book2のsheet2に以下のような表を作る。
 ※枠線がズレてしまっていますが、それぞれが1つのセルと考えてください。
  人物・情報と入力されたセルは見出しです。
  また、1人の人物のデータに対し、その人の情報が3つあるとします。
  
______________
|人物   |   情報   |
_______________

|B君 |  |  |  |
_______________
|C君   | | | |
_______________
|A君 | | | |
_______________


② book1のsheet3に、同じ表があるとする。ただし、情報のセルは記入されている。
 
________________
|人物   |   情報     |
_______________

|A君 |長男|中学生|14歳|
_______________
|B君   |次男|小学生|10歳|
_______________
|C君 |長男|高校生|16歳|
_______________

③book2に設置しているマクロを実行すると、book1/sheet3のデータを読み込み、book2/sheet2の該当する人物のデータに表示されるようにする。但し、①②をみてわかるように、人物の名前の順番は同じではない。



・・・というものです。
最初に作ったプログラムでは、以下のように考えました。

book1/sheet3のUsedRangeから”A君”という文字列を

Set A君1 = Cells.Find(what:="A君", lookat:=xlPart)
で探し、
Selection.Offset(Columnoffset:=1).Select
で1つとなりのセルをActiveにし、
そのActivecellを"A君情報1"という変数にし、Do loopを使ってbook1/sheet3の"情報"セルがが空白になるまで1つずつ右に移動/変数を設定し、その値をbook2/sheet2の該当セルに代入していく・・・・(book2/sheet2の表からも、同じ工程で"A君"を探し、隣のセルに変数を設定する)というものです。そして、C君までの情報を全て出力し終えるというプログラムを作りたいのです。

ちなみに、book2からbook1の呼び出しはできました。

以下が作ってみたプログラムです。↓




'型があっていないとエラーになるため、とりあえずすべてVariant型にしています
Dim SorceFile As Variant, OpenFile As Variant
Dim A君1 As Variant, B君1 As Variant, C君1 As Variant
Dim A君情報1 As Variant, B君情報1 As Variant, C君情報1 As Variant
Dim A君情報2 As Variant, B君情報2 As Variant, C君情報2 As Variant

'現在開いているbook2の名前をSorceFileという変数にする
Set SorceFile = ThisWorkbook
'ファイル(book1)を選択して開く
OpenFile = Application.GetOpenFilename
If OpenFile <> fales Then
Filename = Dir(OpenFile)
MsgBox Filename
Workbooks.Open OpenFile
Else
MsgBox "キャンセルされました"
End If

'開いたファイル(book1)から、"A君"という文字列を探す。見つかったら、1つ隣のセルに移動し、"A君情報1"という変数を設定する。
ActiveSheet.UsedRange.Select
Set A君1 = Cells.Find(what:="A君", lookat:=xlPart)
A君1.Select
A君1.Offset(columnoffset:=1).Select
A君情報1 = ActiveCell

'マクロが設置されているbook2をアクティブにし、同様に"A君"という文字列を探す。見つかったら、1つ隣のセル(空白)に移動し、その空白のセルに"A君情報2"という変数を設定する。
ThisWorkbook.Activate
ActiveSheet.UsedRange.Select
Set A君2 = Cells.Find(what:="A君", lookat:=xlPart)
A君2.Select
A君2.Offset(columnoffset:=1).Select
A君情報2 = ActiveCell




・・・と、ここまではステップインをしながら変数の値を確認できています。、
このあとbook2の空白のセル"A君情報2"にbook1の"A君情報1"の値を代入したいのですが、

ThisWorkbook.Worksheets("sheet2").A君情報2.value = Workbooks(SorceFile).Worksheet("sheet1").A君情報1.value

↑ではコンパイルエラーになります。book2の表、A君の空白の情報で"長男"~"14歳"まで、book1から抽出/出力ができたら、次はB君C君・・・としていきたいのですが、「型が一致しない」や「インデックスが有効範囲にありません」となってしまいます。
この値だけ代入することができれば、私の力でもプログラムを最後まで作成することができるのですが・・・

分かりづらく、しかも玄人の方からすれば何だこのマクロは!!となるかもしれませんが、
どうかアドバイスの程、宜しくお願いいたします。

VBA独学中の初心者です。
ある問題に躓いており、どうしても動かない部分があるため、皆様のお力添えをいただきたいです。
説明が稚拙で分かりづらいかもしれませんが、宜しくお願いいたします。

① 2つのbook(book1/book2)があるとし、登録したマクロはbook2に設置する。
book2のsheet2に以下のような表を作る。
 ※枠線がズレてしまっていますが、それぞれが1つのセルと考えてください。
  人物・情報と入力されたセルは見出しです。
  また、1人の人物のデータに対し、その人の情報が3つあると...続きを読む

Aベストアンサー

こんばんは。

要するに、ソースファイル(データファイル)から情報を取り出す内容なのですね。
それをあえてFind メソッド指定なのかな?

>ActiveSheet.UsedRange.Select
だったら、以下は、Cells ではなくて、Selection でしょうね。

> Cells.Find(what:="A君", lookat:=xlPart)
なぜ、xlPart になっているのでしょうか?表記の乱れがあるということでしょうか?
変数の使い方とか、初歩的なところがまだ出来ていません。

>玄人の方からすれば何だこのマクロは
Findメソッド は、常連さんの某氏の専売特許のようなものですが、私だと、配列からMatch関数を利用しいるのだろうとは思います。玄人的なら、ADODBでしょう。ファイルを直接開けないで可能だからです。もちろん、Excel関数での処理もありますが、あまり格好がよくありません。

私が書くと、こんなコードにしてしまいます。

person info1 info2 info3
A君 長男 中学生 14歳
B君 次男 小学生 10歳
C君 長男 高校生 16歳
D君 三男 大学生 18歳 * 新たな情報が加わった場合も、D君のものだけを取るようにしています。

一旦取得した後に、D君の資料を取り寄せる
B君 次男 小学生 10歳
C君 長男 高校生 16歳
A君 長男 中学生 14歳 
D君 



'//標準モジュール
Sub GetDataAll()
 Dim wb1 As Workbook 'データのソースファイル
 Dim AcSh As Worksheet 'アクティブシート(データを受け取る側)
 Dim c As Range
 Dim r As Range
 Dim startRw As Long '検索文字列の最初の行
 Dim FindArea As Range 'データ・ソースの被検索場所
 Const FNAME As String = "myDATABook.xlsx" 'Thisbook と同フォルダーのファイル名
 Set AcSh = ThisWorkbook.Worksheets("Sheet2")
 
 On Error GoTo ErrHandler
 Set wb1 = Workbooks(FNAME) 'オブジェクトとして認識できるか?できなければ、ErrHandlerに飛ぶ
 
 Set FindArea = wb1.Worksheets("Sheet1").Columns(1) 'ソースファイルの1列目を検索
 With AcSh
  Application.Goto AcSh.Range("A1") 'データをインポートするシートに戻る

  'データに空きがないか調べ、データ検索の初期値の行を求める
  If .Cells(Rows.Count, 1).End(xlUp).Row > .Cells(Rows.Count, _
    2).End(xlUp).Row Then
    startRw = .Cells(Rows.Count, 2).End(xlUp).Row + 1
  Else
    MsgBox "データの取得の必要がありません。", vbExclamation
    Exit Sub
  End If
  
  '単語検索は、ワイルドカードを加える, c.Value & "*" ->LookAt:=xlWhole となる
  For Each c In .Range(.Cells(startRw, 1), .Cells(Rows.Count, 1).End(xlUp))
   If c.Value <> "" Then
    Set r = FindArea.Find(What:=c.Value & "*", LookIn:=xlValues, _
      LookAt:=xlWhole, SearchOrder:=xlByRows, MatchCase:=False, _
      MatchByte:=False)
    If Not r Is Nothing Then
     '配列の受け渡し(非推奨)
     c.Offset(, 1).Resize(, 3).Value = r.Offset(, 1).Resize(, 3).Value
    End If
   End If
  Next
 End With
 Exit Sub
ErrHandler:
 'エラーの発生の場合
 If Err.Number = 9 Then
  If Dir(FNAME) <> "" Then
   Workbooks.Open FNAME
   Resume 'エラーを発生した所まで戻る
  Else
   MsgBox "ファイルが見つからないか、パスを指定してください。", vbExclamation
   Exit Sub
  End If
 Else
  MsgBox Err.Number & " :" & Err.Description & " :" & Erl
 End If
End Sub

'//

 '配列の受け渡し
 c.Offset(, 1).Resize(, 3).Value = r.Offset(, 1).Resize(, 3).Value

入門・初級レベルでは、Copy メソッドのほうが良いでしょう。
r.Offset(, 1).Resize(, 3).Copy c.Offset(, 1)

こんばんは。

要するに、ソースファイル(データファイル)から情報を取り出す内容なのですね。
それをあえてFind メソッド指定なのかな?

>ActiveSheet.UsedRange.Select
だったら、以下は、Cells ではなくて、Selection でしょうね。

> Cells.Find(what:="A君", lookat:=xlPart)
なぜ、xlPart になっているのでしょうか?表記の乱れがあるということでしょうか?
変数の使い方とか、初歩的なところがまだ出来ていません。

>玄人の方からすれば何だこのマクロは
Findメソッド は、常連さんの某氏の専売特許の...続きを読む

Q【VBA】IF文 複数(ネスト)の時の処理について

こんにちは。
if文についておしえてください。
以下のようなマクロがあるとします。

変数 tensuuに-1をいれて実行すると①→②のように動作し「入力エラー」と表示されます。
tensuuに120を入れて実行すると①´→②´の順に動作し「入力エラー1」と表示されます。

どして、-1のときは入力エラー1にはいかず入力エラーにいくのでしょうか?
120のときは入力エラーにはいかず入力エラー1にいくのでしょうか?

動きがよくわかりません。
IF文とELSEはどういう紐づけがされているのでしょうか?

よろしくおねがいいたします。
   
Sub t()
tensuu = -1
If tensuu >= 0 Then '①
If tensuu <= 100 Then '①´
If tensuu >= 80 Then
MsgBox "合格"
Else
MsgBox "不合格"
End If
Else
MsgBox "入力エラー1" '②´
End If
Else
MsgBox "入力エラー" '②
End If
End Sub

こんにちは。
if文についておしえてください。
以下のようなマクロがあるとします。

変数 tensuuに-1をいれて実行すると①→②のように動作し「入力エラー」と表示されます。
tensuuに120を入れて実行すると①´→②´の順に動作し「入力エラー1」と表示されます。

どして、-1のときは入力エラー1にはいかず入力エラーにいくのでしょうか?
120のときは入力エラーにはいかず入力エラー1にいくのでしょうか?

動きがよくわかりません。
IF文とELSEはどういう紐づけがされているのでしょうか?

よろし...続きを読む

Aベストアンサー

If 〜 Then 〜 Else 〜 End If
で1セットです。

ネスト(入れ子)になったIF文というのは、 Then 〜 とか Else 〜 の〜の部分にIf文がくるものです。
ですから、外のIfを越えてしまうことはありません。
よって、一番内側から見ていけば、構造がはっきりします。


一番内側から見ます。

If tensuu >= 80 Then
MsgBox "合格"
Else
MsgBox "不合格"
End If

が1セットです。
これを 「文1」とすると元のプログラムは

If tensuu >= 0 Then '①
If tensuu <= 100 Then '①´
「文1」
Else
MsgBox "入力エラー1" '②´
End If
Else
MsgBox "入力エラー" '②
End If

となります。この状態で「一番内側」を見ると

If tensuu <= 100 Then '①´
「文1」
Else
MsgBox "入力エラー1" '②´
End If
です。これを「文2」とすると

If tensuu >= 0 Then '①
「文2」
Else
MsgBox "入力エラー" '②
End If


余談ですが
この例の場合、外側2つは、判定内容と処理とが離れてしまい、見辛いのは確かです。
if 条件 Then A Else B は if not条件 Then B Else A と同じ、ということから、Thenでの処理とElseでの処理を入れかえれば、
条件の直ぐ下の処理が来るので、見易さが格段によくなります。

If tensuu < 0 Then '① ' tensuu<0 は not (tensuu>=0)と同じ
MsgBox "入力エラー" '②
ElseIf tensuu > 100 Then '①´
MsgBox "入力エラー1" '②´
ElseIf tensuu >= 80 Then
MsgBox "合格"
Else
MsgBox "不合格"
End If ' ElseIfで継いでいるので、ネストにはなっていない

If 〜 Then 〜 Else 〜 End If
で1セットです。

ネスト(入れ子)になったIF文というのは、 Then 〜 とか Else 〜 の〜の部分にIf文がくるものです。
ですから、外のIfを越えてしまうことはありません。
よって、一番内側から見ていけば、構造がはっきりします。


一番内側から見ます。

If tensuu >= 80 Then
MsgBox "合格"
Else
MsgBox "不合格"
End If

が1セットです。
これを 「文1」とすると元のプログラムは

If tensuu >= 0 Then '①
If tensuu <= 100 Then '①´
「文1」
Else
MsgBox "入力エラー1" '②´
...続きを読む

Q【エクセル VBA】CSVファイルの結合

以前同じ質問をさせて頂いたのですが、説明不足であったため再投稿いたします。

【エクセル VBA】
VBAを使って複数のCSVを結合させたいのですが、コンマ区切りの値がデータ上に存在するため上手くまとまりません。

バッチ等でまとめる方法ではなく、どうしてもVBAでやらなければならないので、その方法をご教授下さい。

また、結合するCSVはエクセルを開いた時に選択できるようにしたいです。
(特定のファイル上を対象等では無く。)



現在使用しているVBAは以下のものになります。
-----------------------------------------------------

Sub CsvIn()
'CSVファイルの読み込み
Dim CsvFileName As Variant
Dim Li As String
Dim Bf() As String
Dim R As Long
Dim ShMain As Worksheet
Dim FlNo As Integer
Dim FFlNo As Integer

With ThisWorkbook 'シート&パスの設定
Set ShMain = .Worksheets("Sheet1")
ChDrive .Path
ChDir .Path
End With
'複数のファイルの選択を可に設定
CsvFileName = Application.GetOpenFilename _
(filefilter:="CSVファイル(*.csv),*.csv", _
Title:="CSVファイル選択", MultiSelect:=True)
If VarType(CsvFileName) = vbBoolean Then Exit Sub 'キャンセル時の処置
R = 1 '行の初期値
For FlNo = 1 To UBound(CsvFileName) 'ファイル数分ループ
FFlNo = FreeFile '---使用可能なファイル番号取得
Open CsvFileName(FlNo) For Input As #FFlNo
Do Until EOF(FFlNo) '最終行までループ
Line Input #FFlNo, Li '一行読み込み
Bf = Split(Li, ",") 'カンマで分割し配列に代入
If UBound(Bf) >= 0 Then '空白行の処理を飛ばす
With ShMain '1行分のデータをセルに出力
.Range(.Cells(R, 1), Cells(R, UBound(Bf) + 1)).Value = Bf
End With
End If
R = R + 1
Loop
Close #FFlNo
Next FlNo
End Sub

-----------------------------------------------

参考になりそうなサイト
http://excel-ubara.com/excelvba5/EXCELVBA257.html



よろしくお願いします。

以前同じ質問をさせて頂いたのですが、説明不足であったため再投稿いたします。

【エクセル VBA】
VBAを使って複数のCSVを結合させたいのですが、コンマ区切りの値がデータ上に存在するため上手くまとまりません。

バッチ等でまとめる方法ではなく、どうしてもVBAでやらなければならないので、その方法をご教授下さい。

また、結合するCSVはエクセルを開いた時に選択できるようにしたいです。
(特定のファイル上を対象等では無く。)



現在使用しているVBAは以下のものになります。
------------...続きを読む

Aベストアンサー

No.13 に対する補足コメントについて

ですから!
そのダメな所のデータを数行抜き出したものでCSVファイルを作成して実験してみてください。
それでも症状が出るならばその数行のデータを提示してください。

大変申し訳ないのですが、こちらはそちらの状況が見えないので「特段ルールが異なるようなことはございませんでした。」は、あなたが気づかないだけの場合が多いのでそれを提示していただきたいのです。
「同じ列に似た値があると上書かれてしまうということはありませんでしょうか?」については1文字ずつ「"」「,」が有った時だけ特別な作業をしているだけなので考えにくいです。

もしかしての考えられそうなものとして
・文字コードのせいで1つの2バイト文字が「"」や「,」と何かに分解されてしまっている可能性も有るかもしれません。
・1つの行中で「"」が偶数個でないと誤動作する可能性はあります。
・CSVファイルに特殊な制御コードになりそうな文字が含まれている。
・これは故意にしているのですが空白だけの行は削除していますが問題ないですよね?

とにかく、こちらではそちらの状況が見えないので、ダメな状況を具体的に提示していただけないと実験などが出来ないのです。もしも具体的な提示が出来ないのならばそう言ってください。あなたの事は無視するようにします。
よろしくお願いいたします。

No.13 に対する補足コメントについて

ですから!
そのダメな所のデータを数行抜き出したものでCSVファイルを作成して実験してみてください。
それでも症状が出るならばその数行のデータを提示してください。

大変申し訳ないのですが、こちらはそちらの状況が見えないので「特段ルールが異なるようなことはございませんでした。」は、あなたが気づかないだけの場合が多いのでそれを提示していただきたいのです。
「同じ列に似た値があると上書かれてしまうということはありませんでしょうか?」については1文...続きを読む

Qテキストファイルの途中行から読み込む方法について

こんにちは
テキストファイルの1から2行目をのぞき、3行目からPCへよむといったことは
かのうなのでしょうか?全部よむことはできたのですが、特定の行を指定してなど
読み込む方法がありましたらおしえてください。
宜しくおねがいいたします。

Aベストアンサー

テキストの最後が改行で終わっている場合uboundを-1しますが
そうでない場合は-1しなくてもいいですね

set fs = CreateObject("Scripting.FileSystemObject")
set f1=fs.OpenTextFile("x.txt")
allLine=f1.readALL
lines=split(allLine,vbcrlf)
j=""
for i=3 to ubound(lines)
j=j&vbcrlf&i
next
msgbox j


j=j&vbcrlf&i→j=j&i
とすれば当然改行は入りません

Q最も高い身長を表示するプログラム

5人分の身長から最も高い身長を表示するプログラムをつくったのですが、エラーがでて実行できません。改善すべきところを教えてください。お願いします。
int main(void)
{
double a[5], max = 0;
int i;

for (i = 1; i <= 5; i++)
{
a[i] = 0;
}
printf("数値を5つ入力してください。\n");

for (i = 1; i <= 5; i++)
{
scanf("%lf", &a[i]);
}

for (i = 1; i <= 5; i++)
{
if (a[i] > max)
max = a[i];
}

printf("最も高い身長は%fです\n", max);

return 0;
}

Aベストアンサー

double a[5] ;
と宣言したら、安全に使えるのは a[0] 〜 a[4] です。

なので、このプログラムを安全なものにするなら
・double a[5]はそのまま、 i=0;i<5;i++ にして、 i=0〜4 の範囲で使う
・「i = 1; i <= 5; i++は変えない」 のなら
 ・ i=1〜5を、 0〜4 に対応させて使う
   単純明快なのは、 a[i-1] とすること
 ・double a[5+1] と宣言して、a[5] を安全に使えるようにする。
   a[0] が無駄になるけど気にしない


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング