Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


184 / 3841 ページ ←次へ | 前へ→

【78773】Re:エクセルの指定セルをテキストデータ...
質問  かわかみまめお  - 17/1/23(月) 1:13 -

引用なし
パスワード
   β様、ありがとうございます。
γ様へのお礼(返信)と重複しますが、その後、少しずつですが、御教示に従い、自分でも調べました。

タブですが、頂いた、=CODE(MID(B1,ROW(A1),1) で、元のエクセルのセル内を調べたところ、全て「10」という値になりました。
そこで、
Print #1, SaveD を
Print #1, Replace(SaveD, vbLf, vbCrLf)に変更すること、また、そもそものエクセルのっ雛型を自分でも処理できるように変更して、なんとか最低限の目標を達成することができました。 エクセルのVBAもよくわかっていない自分が、エクセル以外のものを操作するということの難しさを改めて感じました。

どうもありがとうございました。


なお、甘えてしまって恐縮ですが、追加で御教示頂きたいのですが、テキストファイルが、カレントフォルダに作成されますが、これを常時、元のエクセルがあるフォルダと同じフォルダ内に作成するためには、どのような構文を書き加えたらよろしいでしょうか。
・ツリー全体表示

【78772】Re:エクセルの指定セルをテキストデータ...
質問  かわかみまめお  - 17/1/23(月) 1:10 -

引用なし
パスワード
   γ様、ありがとうございます。
その後、少しずつですが、自分でも調べました。

(1)ステップ実行をして、イミディエイトウインドウを見ながら、
SaveDの変化を確認しました。考えてようやく、理解できました。
(自分では、saveD の値が、AAA、次が、AAAタブBBB 次が、AAAタブBBBタブCCC
と累積していく場合に、前の分を書き込んでからでないと、コンピュータは、忘れてしまうのではないか、という考えがあったもので、このような質問をしてしまいました。)

(2)セルの複数行についても、β様からの御教示もあり「タブに関する、エクセルとwindows の違い」なども参考にしました。今の自分では、ちょっと難しいので、
元のエクセルの雛型を以下のようにしました。
  
      A列                B列
1行目 ファイル名となる文字列(XXX) テキストに書き出す内容(セル内複数行)
2行目 ファイル名となる文字列(YYY) テキストに書き出す内容(セル内複数行)

そして、セルの指定は、複数セルの「範囲」ではなく、セル「B1」しか選ばず、XXXファイルを作成する、ことににしました。そのために、
Print #1, SaveD を
Print #1, Replace(SaveD, vbLf, vbCrLf) へ変更することにより、最低限の目的は達成できました。(次の目標は、「B1:B2」を選んで、一気にXXX とYYYのファイルを作成することです。)

本当にどうもありがとうございました。

(3)γ様、もう一点教えて頂きたいことが出てきました。
今回は、テキストファイルが、カレントフォルダに作成されますが、これを常時、元のエクセルがあるフォルダと同じフォルダ内に作成するためには、どのような構文を書き加えたらよろしいでしょうか。
・ツリー全体表示

【78771】Re:マクロで保存したい
お礼  北風  - 17/1/19(木) 13:46 -

引用なし
パスワード
   ▼β さん
対応有難うございます。思い通りの仕組みでした
有難うございました


▼β さん:
>▼北風 さん:
>
>↑
>
>単純に、直接保存をしています。
>ただ、xl2003の環境がないので、試してはいません。
>たしか、この書き方で充分だったような記憶です。
・ツリー全体表示

【78770】Re:マクロで保存したい
発言  β  - 17/1/18(水) 18:16 -

引用なし
パスワード
   ▼北風 さん:



単純に、直接保存をしています。
ただ、xl2003の環境がないので、試してはいません。
たしか、この書き方で充分だったような記憶です。
・ツリー全体表示

【78769】Re:マクロで保存したい
発言  β  - 17/1/18(水) 18:15 -

引用なし
パスワード
   ▼北風 さん:

Sub Test()
  Dim fm As String
  With ThisWorkbook.ActiveSheet
    fm = "S:\TTT\わい\" & .Range("E24").Value & "(" & .Range("H24").Value & ").xls"
  End With
  ThisWorkbook.SaveAs fm
End Sub
・ツリー全体表示

【78768】Re:マクロで保存したい
発言  北風  - 17/1/18(水) 15:37 -

引用なし
パスワード
   ▼β さん:
>▼北風 さん:
>
>保存フォルダ、保存ファイル名は決まっているのですから ダイアログボックスを開く必要はなく
>直接保存すればいいのですが?
>
>それとも、保存フォルダも保存ブック名もダイアログ上で変更したいということですか?
>
>それと、拡張子が xls ですから、実行環境は xl2003以前ということですね?
>
>あと、SaveAs は、今開かれている、このマクロブックを名前をつけて保存します。
>実行後、エクセル画面には元のマクロブックは残っていません。
>新しく作られたブックが残っています。
>
>一方、SaveCopyAs というのがあります。
>これは、マクロブックはそのままで、『裏で』新しい名前のブックを作成保存します。
>この場合、新しいブックはエクセル画面上には登場しません。
>
>どちらがご希望ですか?
>
>それと、質問とは関係ないことですけど、If fs = False Then End
>
>これでも不具合は発生しませんが
>
>If fs = False Then Exit Sub
>
>こうしておいたほうがいいですよ。
>今回のコードでは全く同じなんですが、今後、複雑な構成のマクロを組み立てていくときに
>End ステートメント を使っていると、保守フェーズで苦労しそうですから。


βさん何時もありがとうございます。
ダイアログボックスを開く必要はなく、直接保存の方法でお願いいたします。
また、貴重なご指摘も有難うございます。
・ツリー全体表示

【78767】Re:マクロで保存したい
発言  β  - 17/1/18(水) 14:03 -

引用なし
パスワード
   ▼北風 さん:

保存フォルダ、保存ファイル名は決まっているのですから ダイアログボックスを開く必要はなく
直接保存すればいいのですが?

それとも、保存フォルダも保存ブック名もダイアログ上で変更したいということですか?

それと、拡張子が xls ですから、実行環境は xl2003以前ということですね?

あと、SaveAs は、今開かれている、このマクロブックを名前をつけて保存します。
実行後、エクセル画面には元のマクロブックは残っていません。
新しく作られたブックが残っています。

一方、SaveCopyAs というのがあります。
これは、マクロブックはそのままで、『裏で』新しい名前のブックを作成保存します。
この場合、新しいブックはエクセル画面上には登場しません。

どちらがご希望ですか?

それと、質問とは関係ないことですけど、If fs = False Then End

これでも不具合は発生しませんが

If fs = False Then Exit Sub

こうしておいたほうがいいですよ。
今回のコードでは全く同じなんですが、今後、複雑な構成のマクロを組み立てていくときに
End ステートメント を使っていると、保守フェーズで苦労しそうですから。
・ツリー全体表示

【78766】マクロで保存したい
発言  北風  - 17/1/18(水) 13:38 -

引用なし
パスワード
   下記コードでファイル名を付けて保存していますがダイアログボックスが、表示され都度保存ボタンを押しますがマクロで保存するようにしたいのですが。

Sub セルの値をファイル名にする()
Dim fm As String
Dim fs As Variant
ChDrive "S:\TTT\わい\"
ChDir "S:\TTT\わい\"
With ThisWorkbook.ActiveSheet
 fm = .Range("E24").Value & "(" & .Range("H24").Value & ")"
End With
fs = Application.GetSaveAsFilename(fm, "MicrosoftExcelブック(*.xls),*.xls", , "ファイルを保存する", "保存")
If fs = False Then End
ThisWorkbook.SaveAs fs
End Sub

宜しくお願いします
・ツリー全体表示

【78765】Re:エクセルの指定セルをテキストデータ...
発言  かわかみまめお  - 17/1/17(火) 19:20 -

引用なし
パスワード
   β様

お世話になります。
かわかみまめおです。

β様も、ご丁寧に御教示ありがとうございます。
β様にも申し訳ないので、いただた内容をもう少し自分で勉強致します。
お時間を頂いて、またご質問させていただくことになるかと思いますが、
その際は宜しくお願いいたします。
・ツリー全体表示

【78764】Re:エクセルの指定セルをテキストデータ...
発言  かわかみまめお  - 17/1/17(火) 19:18 -

引用なし
パスワード
   γ様

お世話になります。
かわかみまめおです。
ご丁寧に御教示ありがとうございます。
あまりに自分が勉強不足でしたので、いただた内容をもう少し自分で勉強致します。
お時間を頂いて、またご質問させていただくことになるかと思いますが、
その際は宜しくお願いいたします。
・ツリー全体表示

【78763】Re:エクセルの指定セルをテキストデータ...
発言  β  - 17/1/17(火) 9:53 -

引用なし
パスワード
   ▼かわかみまめお さん:

↑ で =CODE(MID(B1,ROW(A1),1)  と書きましたが
=CODE(MID($B$1,ROW(A1),1) に直してください。
・ツリー全体表示

【78762】Re:エクセルの指定セルをテキストデータ...
発言  β  - 17/1/17(火) 9:41 -

引用なし
パスワード
   ▼かわかみまめお さん:

γさんからポイントをついたレスがでていますので蛇足です。

●まず、作成したいテキストファイルなんですが、

 ・単に各列のセルの値を単純につなげたものを1行として扱う形のファイルですか?
 ・各列のセルの項目間にタブを挟んだものを1行にした形のファイルですか?

 アップされたコードで作成しているファイルは後者です。

 違いは、このファイルをエクセルからブックとして開いたときに

 前者は各セルの値が連結されて、すべて A列に表示されます。
 後者は各セルの値が各列に分かれて、いかにもエクセルブックらしく表示されます。

 両者をメモ帳で開いても、その違いがわかると思います。

 後者のファイルを タブ区切りのテキストファイルと呼んだりします。
 (作成したいのはこちらのほうだと思いますが?)

●たとえば A1 に aaa 、B1 に bbb、C1 に ccc という3列のセルの1行だけを
 テキストファイルとして書きこんだ時に、できあがったファイル
 をバイナリーエディターソフトで調べると、

 前者 は aaabbbccc改行
 後者 は aaaタブbbbタブccc改行

 こんなようになっていることがわかります。
 エクセルでブックとして開いた場合、タブコードがあれば、セルがわかれます。
 行の最後の改行コードは、その行は、そこでおしまいということを意味します。
 もし、この後にもデータが続けば、そのデータはエクセル上の次の行に表示されます。

● Print ステートメント

 これについては ネット で Printステートメント を検索語にして検索し
 h tps://msdn.microsoft.com/ja-jp/library/office/gg264278.aspx 等、
 でてきたページのわかりやすいものを選んで、読んでおかれることをおすすめします。

 Print 文字列  とやると 文字列の最後に改行が付加された形で書きこまれます。
 文字列は、1行毎のものでもいいですし、全行分を改行コードを適切にいれた形の文字列にして
 その全行分文字列を一挙に書きこんでもOKです。
 アップされたコードでは、各行の最後に改行をつけた全行分の文字列を1回で書きこんでいます。

●エクセルのセル内での改行処理

 セル内で改行されている各行を分解して取り出すということについては、いろいろ方法が
 あります。そこは、いかようにでもできます。

 その改行コードのことをメモします。

 アップされたコードでも使っている vbCRLF 、これが Windows の標準の改行コードです。
 値は2桁、CR(13)とLF(10)が合わさったものです。

 一方、エクセルのセル上で、文字をタイプして、Alt/Enterで入力した時にセットされるコードは
 1桁のLF(10) です。

 念のため、セル内の改行コードが LF でセットされているのかその他の改行コードになっているのかを
 確認しておかれたらいいと思います。

 たとえば、B1 がセル内改行で3行になっていたとします。
 どこかのセルに =LEN(B1) といれます。そのとき表示された数値が、見た目の文字列合計の長さより
 2桁多ければ 1桁の改行コード、4桁多ければ 2桁の改行コードが使われているということになります。

 で、別のセルに =CODE(MID(B1,ROW(A1),1) と打ち込みます。
 これを =LEN(B1) で表示された数値分、下にフィルコピーします。
 そこででてくる文字コードを見ます。10 とか 13 とかといった改行コードも現れますので
 セル内で使われている改行コードが実際にはどんな値なのか(どんな値の組み合わせなのか)が
 わかると思います。

 それを教えてもらえれば、セル内改行を処理する具体的なコード例の回答もよせられると
 思います。
・ツリー全体表示

【78761】Re:エクセルの指定セルをテキストデータ...
発言  γ  - 17/1/17(火) 7:29 -

引用なし
パスワード
   うーん、
SaveDという文字列変数に
・一行の中の各セルの値を、タブ記号を挟んで連結し、
・行と行の間は改行記号を挟んで連結
しておき、それをまとめてファイルに書き込んでいるわけで、
どのあたりが不明ですか?

タブ記号というのが何かは分かりますか。

「改行」というのがある種の動作とイメージされているのに、
「単に改行記号という文字を連結することである」といった
あたりが理解しにくいのかなあ。

ステップ実行というのは知っていますか?
一行毎に実行して、SaveDにどんな値がセットされるかを
ローカルウインドウで確認してみると実感が湧くと思います。

> ループして最後にprintするのでしょうか。
> 1つのセルごとにprintする必要があるのではないのか、と思いました。
なぜ纏めて書き込むとまずいのでしょうか?
セル毎に書き込むこともできるのでしょうが、
そうしないといけないわけでもありません。

-----------------------
(2)は、
いったん、表示上の一行単位で、
一セルを複数行に分割していくとよいのでしょう。

ただし、あくまで例のようで、
コードを出しても、いやいや実際はこうです、
ということになりそうなので、少し待ちます。
まずは、最初の点に取り組むことから初めて下さい。
それが出来ない限り、二つの目のテーマに取り組んでも無駄ですから。

# 日中はアクセスしませんので、返事を頂いても反応は夜以降になります。
・ツリー全体表示

【78760】エクセルの指定セルをテキストデータに書...
質問  かわかみまめお  - 17/1/16(月) 21:02 -

引用なし
パスワード
   お世話になっております。
かわかみまめおと申します。

1. 下記のようなエクセルファイル(A)があったとします。
      A    B      
 1   文字  文字(3行)  
  2   文字  文字(3行) 

2.選択した範囲の一番左上をファイル名として、テキストファイルに書き出すコードとして、WEBで調べていたら、下記のコードを書いてる方がいらっしゃいました。

======
Sub selection_save_txt()
'
'選択範囲の左上のセルの値をファイル名にして、選択範囲をTXTとして出力する
'保存先はカレントフォルダ
'

Dim i, j As Integer
Dim d, SaveD As String
Dim start_row, start_column, end_row, rows_count, columns_count, end_column As Long
Dim File_name As Variant

'範囲を調べる
  start_row = Selection.Row                '開始行
  start_column = Selection.Column             '開始列
  end_row = start_row + Selection.Rows.Count - 1     '終了行
  end_column = start_column + Selection.Columns.Count - 1 '終了列
  rows_count = Selection.Rows.Count            '範囲行数
  columns_count = Selection.Columns.Count         '範囲列数
  
'左上のセルの値をファイル名にする
  File_name = Cells(Selection.Row, Selection.Column).Value
   
   
'ファイルの読み込みと出力
  Open File_name & "_j.txt" For Output As #1
  
  For i = start_row To start_row + Selection.Rows.Count - 1
    For j = start_column To end_column
      d = Cells(i, j)
      SaveD = SaveD & d & vbTab   '1列ごとにTABコード追加
      'Debug.Print SaveD
    Next j
    SaveD = SaveD & vbCrLf       '1行ごとに改行を追加
  Next i
  
  Print #1, SaveD
  Close #1
End Sub

===================

3.ご教示頂きたいこと

(1)上記のFor 以下の記述において、
■SaveD = SaveD & d & vbTab 
■SaveD = SaveD & vbCrLf 
の構文(?)の意味がよくわかりませんでした。
(変数とセルとタブを&でつなげる?)

また、最後に、
■Print #1, SaveD
とありますが、printは記入することだと調べました。
ループして最後にprintするのでしょうか。1つのセルごとにprintする必要があるのではないのか、と思いました。

なぜ、これで、上手に動作するのか理解できませんでした。
どなたかご教示頂けないでしょうか。


(2)なお、B1のセルは、セル内での改行を利用しており、テキストファイルにおいても、行が分かれるようにしたいのですが、いかがすればよろしいでしょうか。

御教示どうぞよろしくお願いいたします。
・ツリー全体表示

【78759】Re:型が一致しないエラーについて
回答  γ  - 17/1/15(日) 9:03 -

引用なし
パスワード
   >型の不一致の問題、その他の問題も解決し意図した通りに動きました!
どんな風にされたのか、折角ですから示して欲しいものですね。
それは閲覧しているかたにも参考になりますしね。
・ツリー全体表示

【78758】Re:型が一致しないエラーについて
発言  γ  - 17/1/14(土) 14:42 -

引用なし
パスワード
   ああ、単に
Set pos1 = Cells(pos1row, pos1col)
だけで良かったですね。

次のpos1に進めるときは、
提案の形で、結合セルの行数を調べたほうがよいとは思うが。
・ツリー全体表示

【78757】Re:型が一致しないエラーについて
お礼  VBA勉強中  - 17/1/14(土) 14:14 -

引用なし
パスワード
   ▼γ さん:
ありがとうございます!
型の不一致の問題、その他の問題も解決し意図した通りに動きました!
>まずそのことを念頭におくと、
>  Set pos1 = Cells(pos1row, pos1col).MergeArea
>  Set pos1 = pos1(1)
>としてしまう方法があります。
>(最初だけでなく、複数箇所変更が必要です)
変数名(インデックス番号)で扱うことができるのですね
また、配列について調べていると最初に同じ型、同じような変数をたくさん定義するのがいかに無駄になるかわかりました。ありがとうございます

今回は無事に動きましたので特に修正はしないと思いますが、次回からはタブ、配列を念頭に置いて、見やすいものをかけるように心がけます。

ありがとうございました!!
・ツリー全体表示

【78756】Re:型が一致しないエラーについて
回答  γ  - 17/1/14(土) 13:40 -

引用なし
パスワード
   つっこみどころがいくつかあります。

型の不一致ですが、それは、pos1が結合セルの場合、
pos1.Valueが配列になるからです。

配列と一つの値を = で比較することはできません。

まずそのことを念頭におくと、
  Set pos1 = Cells(pos1row, pos1col).MergeArea
  Set pos1 = pos1(1)
としてしまう方法があります。
(最初だけでなく、複数箇所変更が必要です)

その他。

(1)1行ずつ行送りすると無駄かもしれない。
  pos1row = pos1row + sh1.Cells(pos1row, pos1col).MergeArea.Rows.Count
  とするとよいかも。

(2) name1,name2などを繰り返しの中で定義する必要はない。

(3) memo = "ee" などとダイレクトに文字をコードに書くなら、
  name1 などと変数を使わないほうが直感的かもしれない。
  memo に書き込む値も文字列変数で定義するか、いずれ統一が必要。

(4)Case Is = name1 は、普通は Case name1 で良い。

(5)投稿にあたっては、コピーペイストしてください。
  memo = bb1" & Right(pos1.Offset(, 3).Value, 5) & "bb2" _
                & Left(pos1.Offset(, 3).Value, 4) & "bb3"
  などというのはコンパイルエラーになる。
(6)インデントが恣意的です。タブを使ってください。
・ツリー全体表示

【78755】型が一致しないエラーについて
質問  VBA勉強中  - 17/1/14(土) 11:47 -

引用なし
パスワード
   以下自分で書いてみたものです。
原因はrange型の変数とstring型の変数を=で結んだからかな?と予想していますが、どう書き換えたらいいのかわかりません。ご教授お願いします…

Sub test()
Application.ScreenUpdating = False

  Dim sh1 As Object
  Dim pos1 As Range
  Dim pos1row As Long
  Dim pos1col As Long
  Dim name1 As String
  Dim name2 As String
  Dim name3 As String
  Dim name4 As String
  Dim name5 As String
  Dim name6 As String
  Dim name7 As String
  Dim name8 As String
  Dim name9 As String
  Dim memo As Range
  
  Set sh1 = Sheets("sheet1")
  
  pos1col = 8
  pos1row = 5
  Set pos1 = Cells(pos1row, pos1col).MergeArea
  Set memo = pos1.Offset(, 7)
  
  Do While Not IsEmpty(pos1)
    name1 = "a"
    name2 = "b"
    name3 = "c"
    name4 = "d"
    name5 = "e"
    name6 = "f"
    name7 = "g"
    name8 = "h"
    name9 = "i"
      Select Case pos1.Value
          Case Is = name1
            memo = "aa"
          Case Is = name2
            memo = "bb1" & Right(pos1.Offset(, 3).Value, 5) & "bb2" _
              & Left(pos1.Offset(, 3).Value, 4) & "bb3"
          Case Is = name3
            memo = bb1" & Right(pos1.Offset(, 3).Value, 5) & "bb2" _
              & Left(pos1.Offset(, 3).Value, 4) & "bb3"
          Case Is = name4
            memo = pos1.Offset(, 3).Value & "dd"
          Case Is = name5
            memo = "ee"
          Case Is = name6
            memo = "ff"
          Case Is = name7
            memo = pos1.Offset(, 3).Value & "gg"
          Case Is = name8
            memo = "hh"
          Case Is = name9
            memo = pos1.Offset(, 3).Value & "ii"
      End Select
      
    pos1row = pos1row + 1
    Set pos1 = sh1.Cells(pos1row, pos1col).MergeArea
    
  Loop


End Sub
・ツリー全体表示

【78754】Re:特定の文字列と特定の文字列の間にあ...
お礼  藁にもすがりたい者  - 17/1/13(金) 15:25 -

引用なし
パスワード
   ▼β さん:

すごい…違うケースも想定してのコード作成を…
感動で胸が一杯です…

こちらでも私の思い描いた形になりました!

私のようなマクロを理解していない者にも
暖かく対応していただき、ありがとうございました!


>▼藁にもすがりたい者 さん:
>
>元シート(コードでは "Sheet1") の店名ですが、
>必ずしも、まとまって(固まって)出現しないというケースも想定しますと
>以下にしておいたほうが安全ですね。
>
>Sub Test2()
>  Dim r As Range
>  Dim a As Range
>  Dim d As Range
>  Dim i As Long
>  Dim dic As Object
>  Dim nm As String
>  Dim pos As Range
>  
>  Set dic = CreateObject("Scripting.Dictionary")
>  
>  With Sheets("Sheet1")
>    Set r = .Range("B6", .Range("B" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeConstants, xlNumbers)
>    
>    For Each a In r.Areas
>      Set d = a.Offset(-1).Resize(a.Rows.Count + 1)
>      nm = d(1).Value '店名
>      If Not dic.exists(nm) Then '初めて出現?
>        dic(nm) = True
>        If Not IsObject(Evaluate(nm & "!A1")) Then 'シート無し?
>          Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = nm
>        End If
>        With Sheets(nm)
>          .Cells.ClearContents
>          Set pos = .Range("A1")
>        End With
>      Else
>        Set pos = Sheets(nm).Range("A" & Rows.Count).End(xlUp).Offset(1)
>      End If
>      d.EntireRow.Copy pos
>    Next
>    
>  End With
>End Sub
・ツリー全体表示

184 / 3841 ページ ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free