- ベストアンサー
エクセルでVBE作成
- エクセルでVBE作成について教えてください。
- 英文データをアットランダムに変換する方法を知りたいです。
- VBEを使って単語や文をばらばらにすることは可能ですか?
- みんなの回答 (11)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 すみません。やっと意味が分かりました。 もう少し、きちんと読んでいればよかったです。 'I'(私) のみは、大文字ということですね。 私は、その意味を理解できていませんでした。それは、考えてもみなかったです。 こうなればよいのですね。 ------------------------------------------- I am from China. from I am China . What is this? is this what ? Shall I open the door? door I open shall the ? -------------------------------------------- にするためには、先頭の文字を小文字にするオプションとして、 '先頭の文字を小文字にするオプション '先頭から2文字のI(大文字のI)+" "(半角スペース)は除外 If StrComp(Mid$(buf, 1, 2), "I ", vbBinaryCompare) <> 0 Then buf = StrConv(Mid$(buf, 1, 1), vbLowerCase) & Mid$(buf, 2) End If このようなオプションを入れてください。 この場合、先頭から2文字のI(大文字のI)+" "(半角スペース)のみになっているものに対しては除外されます。ただし、固有名詞に関しては、小文字になってしまいます。その場合、辞書として、リストを作らなくてはなりません。WorksheetFunction.Match(検索語,リスト,0) として、ヒットした場合は、除外ということになります。少し、またコードが難しくなります。
その他の回答 (10)
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 返事が遅くなりました。 >先頭の文字を小文字にするオプション ←【不要】 >'割愛 ←【不要】 >となっていますので >buf = StrConv(Mid$(buf, 1, 1), vbLowerCase) & Mid$(buf, 2) >を入れて実行しますと 何も手を加えないで、そのまま使ってください。「割愛」とい言葉、入れてくださいという意味ではありません。単に、私自身の記録のために入れたので、「割愛」という言葉は無視してください。それは、入れたら、小文字になります。
補足
何度も何度も本当に申し訳ありません。 複雑なコードを作るだけでも大変だったと思います。 その上に、何回も回答でお手間をかけて悪いと思っています。 buf = StrConv(Mid$(buf, 1, 1), vbLowerCase) & Mid$(buf, 2) これを入れないと先頭の語が大文字のままになりますので、入れるのですが文頭の I だけが 小文字にかわってしまいます。 I am from China → China am from i . What is this? → this what is ? Shall I open the door? → the door open I shall ? 下の2つはぴったりなんですが、一番上の I が i に変わります。 I が文中にあるときはいいのですが、文頭にあるときがまずいのです。 CHAR(105) CHAR(73) を使ってなんとかしようと試みましたが うまくいきません。 '割愛 の「 ’」の意味は理解しております。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 >文頭の単語は小文字に変換します。 >ただ、いつも大文字でないといけない 「私はの I」 までが 小文字の i に変わると>困るのです。 「私はの I」 だけはいつも I にしておきたいのです。 ご質問が良く理解できません。その部分は前回から説明したはずで、最初のコードでも、私の指摘した部分で修正が利くはずです。ただ、それを再度指摘されたので、分からないと思い修正をして、#8で新たに書き出しました。#8のコードだけで出来るはずです。 私の出した出来上がりのサンプル文が、想定していない部分があるなら、ご指摘ください。 this that rise day up nation will a live meaning out its true of dream the one have creed and I . この最後の"I" になりますが、これは、元の文章がそうなっているからです。元の文が、大文字のI を入れる限りは、"I" になるはずです。小文字で入れているなら別です。意味が違いますか? 今回のマクロは、どこにも大文字・小文字の変更はさせていないはずです。登録されたマクロを調べていただけませんか?チェックする方法は、(VBEの左枠をクリックすると●が入る)ブレークポイントを取って、そのコードが通っているか調べてみれば分かります。マクロを走らせると、その部分でとまります。 今までのマクロのコードが混じっているのではありませんか? 前のものが修正がされていないなら、残さずに削除してください。もしくは、新規のシートのVBEditor で、標準モジュールを挿入して、#8のコードで試してみてください。 大文字を小文字に変更するのは、StrConvというVBA関数で、引数は、vbLower というものです。検索で、StrConv を探し、引数にvbLower という名称が入っているものがあれば、その部分で小文字にしますから、その部分のコードは違いますから、削除してください。 また、こちらが、全面的に意味を取り違えているなら、ご指摘ください。その場合は、直します。
補足
ご丁寧なお返事、解説をいただき本当にありがとうございます。 #8のコードで '先頭の文字を小文字にするオプション '割愛 となっていますので buf = StrConv(Mid$(buf, 1, 1), vbLowerCase) & Mid$(buf, 2) を入れて実行しますと Had I known you were in hospital, I would have visited you. は希望通り have known I hospital, you you I visited had were would in .となります。 しかし、 I want to see him. は him i want to see . となります。 今までのマクロのコードが混じらないように削除して、実行していますが 何度試しても同じ結果になります。 これ以外は完ぺきにいけます。 せっかくいろいろと解説していただいていますので、私のやり方がまずいのかと思って点検していますが、堂々巡りが続いています。 また、明日、がんばってみます。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 #6 の補足 >私は の I が i になってしまうのが困っていました。 >自分でいろいろやってみるのですが、うまくいきません。 >よろしくお願いします。 前のものとコードが交じり合っているようですね。 一応、最終校として、もう一度、アップしておきますので、これも、別の標準モジュールに入れて、前のものは削除してしまえば、交じり合うこともないと思います。 今回の並べ替え I have a dream that one day this nation will rise up and live out the true meaning of its creed. ↓ this that rise day up nation will a live meaning out its true of dream the one have creed and I . それから、細かいことですが、この並べ替えには、長く繰り返していると、なぜか、癖を感じることがあります。一応、乱数ジェネレータの初期化はしているのですが、これは、パソコン自体の限界だと思ってください。 それと、少し直したのは、数千回に1度かそれ以下の確率で、元の文とまったく同じ並びに出てくる可能性があります。少なくとも、10数単語レベルでは、いくらランダムでも同じものが出てきますので、同一の場合は、再シャフルするためのループを設けました。 もう一つは、最初のご質問では、最後尾の[.(ピリオド)][!(エクスクラメーション]) などは、並べ替えられても最後尾に来ているようでしたので、それも修正しました。 なお、現行では、英語のみです。フランス語などの場合は、Unicode 扱いになりますので、最初の2バイト文字・チェックの部分が変わります。 #7 の問題、辞書をみないで、foul と tummy は、しばらく考えてしまいましが、なんとか解けます。VBAでも、もちろん可能です。 問題は、大学入試レベルぐらいだと思いました。私も、英語が主ですが、あまりに英語が上達しないので、暇つぶしに、VBAを言語として学びました。語学の勉強の仕方と、非常に良く似ていますが、聴くこと話すことはないので、少なくとも英語よりは、遥かに簡単です。単語だって、1,000語も覚える必要はありません。 もし、ついでもありましたら、ご質問を加えてください。この際、出来ることは協力します。久々に、楽しませていただいております。 -------------------------------------------------------- Sub RandamPickUpWords2() Dim c As Variant Dim buf As Variant Dim org As String Dim m As Long Dim i As Long, j As Integer Dim e As Integer Dim arBuf As Variant Dim tmp As String Dim lastwd As String i = 1 '書き出しの行の初期値 j = 3 '書き出しの列の初期値 Application.ScreenUpdating = False For Each c In Range("A1", Range("A65536").End(xlUp)) '2バイト文字除外チェック If VarType(c.Value) = vbString Then buf = StrConv(Trim(c.Value), vbNarrow) org = buf '先頭の文字を小文字にするオプション '割愛 If Len(buf) = LenB(StrConv(buf, vbFromUnicode)) Then '修正箇所 If Right(buf, 1) Like "[!-@]" Then lastwd = Right$(buf, 1) buf = Mid$(buf, 1, Len(buf) - 1) End If buf = Split(buf, Space(1)) m = UBound(buf) + 1 Do arBuf = rndWord(buf, m) tmp = Join(arBuf, Space(1)) e = e + 1 If e > 10 Then Exit Do '無限ループ保護 Loop While Mid$(org, 1, Len(org) - 1) = tmp Cells(i, j).Value = tmp & " " & lastwd i = i + 1 lastwd = "" End If End If Next c Application.ScreenUpdating = True End Sub Function rndWord(ar, m) Dim myCol As New Collection Dim arBuf As Variant Dim n As Integer Dim i As Integer, j As Integer, k As Integer ReDim arBuf(UBound(ar)) For i = 1 To m myCol.Add ar(i - 1) Next i Randomize For j = m To 1 Step -1 k = Int(Rnd() * j) + 1 arBuf(n) = myCol.Item(k) myCol.Remove (k) n = n + 1 Next j rndWord = arBuf Erase arBuf End Function
補足
何度もおつきあいいただいて恐縮です。 ちょっとバタバタしており書込みが遅れて申し訳ありませんでした。 私の文がまずかったようで、うまく伝わっていなかったようです。 文頭の単語は小文字に変換します。 ただ、いつも大文字でないといけない 「私はの I」 までが 小文字の i に変わると困るのです。 「私はの I」 だけはいつも I にしておきたいのです。 何回もお手数をおかけして申し訳ありません。 >VBAを言語として学びました。 こんな勉強の仕方もあるのですね。かなり論理的な思考力も必要だと思います。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 こちらの勝手なことを考えてしまいましので、ご希望のものとは違うものにしてしまい、たいへんすみませんでした。 できましたら、使用用途を教えていただけるとありがたいです。 問題としては、両方とも作るのは簡単でも、解くほうは、そんなに簡単なものではないと思います。 1. の単語の並べ替え コードは、前回のものをほとんど流用しました。 CheckWord()サブルーチンの中の If Len(mWord) > 2 Then を If Len(mWord) > 1 Then に訂正しました。間違いがありました。 ですから、前の以下の二つは削除して、 Private Sub CheckWord(ByRef mWord As String) Function rndChar(mWord As String) 別の標準モジュールを追加して、そちらに置いたほうが分かりやすいと思います。 -------------------------------------------------------- Sub RandamWordsSentence() 'センテンスはそのままで単語だけ入れ替える Dim c As Variant Dim buf As Variant Dim ArBuf() As String Dim tmp As String Dim m As Long Dim i As Long, j As Integer, k As Integer Dim lastwd As String i = 1 '書き出しの行の初期値 j = 3 '書き出しの列の初期値 For Each c In Range("A1", Range("A65536").End(xlUp)) '2バイト文字除外チェック If VarType(c.Value) = vbString Then buf = StrConv(Trim(c.Value), vbNarrow) 'buf = StrConv(Mid$(buf, 1, 1), vbLowerCase) & Mid$(buf, 2) If Len(buf) = LenB(StrConv(buf, vbFromUnicode)) Then '最後尾のピリオド分離 If Right(buf, 1) Like "[!-@]" Then lastwd = Right(buf, 1) buf = Mid$(buf, 1, Len(buf) - 1) End If buf = Split(buf, Space(1)) ReDim ArBuf(UBound(buf)) For n = LBound(buf) To UBound(buf) tmp = buf(n) CheckWord tmp ArBuf(n) = tmp Next Cells(i, j).Value = Join(ArBuf(), Space(1)) & " " & lastwd i = i + 1 End If End If Next c End Sub Private Sub CheckWord(ByRef mWord As String) '戻り値が同じ文字列を排除するためのサブルーチン Dim a As String If Len(mWord) > 1 Then a = rndChar(mWord) Do While mWord = a a = rndChar(mWord) Loop mWord = a End If End Sub Function rndChar(mWord As String) 'ランダム文字並べ替え Dim buf As String Dim myCol As New Collection Dim n As Integer Dim i As Integer, j As Integer, k As Integer buf = "" n = Len(mWord) If n <= 1 Then rndChar = mWord: Exit Function If n = 2 Then rndChar = Mid$(mWord, 2, 1) & Mid$(mWord, 1, 1): Exit Function For i = 1 To Len(mWord) myCol.Add Mid(mWord, i, 1) Next i Randomize For j = n To 1 Step -1 k = Int(Rnd() * j) + 1 buf = buf & myCol.Item(k) myCol.Remove (k) n = n + 1 Next j rndChar = buf End Function
お礼
度々、即座に私の希望を叶えていただいて本当にありがとうございました。 使用用途ですが、自分で単語や文法、構文を覚える時に、練習ドリルを作っています。ただ単に英語、日本語の対比だけで覚えるよりも、このほうがずっと効果が上がります。 単語だけに関してはいろいろ作れたのですが、文章は始めたばかりです。 大変なお手間をおかけして申し訳ありませんでした厚く御礼申し上げます。 ^^^^^^^^^^^^^^^^^^^^^^ サッと見つける 6つの選択問題 junk 進む sill 小さい子供 tot 腐らせる rot 詰まらせる clog がらくた proceed 敷居 cannibal ひどい、下品な rotter はがれる rump ろくでなし nauseating 人食い人種 foul 尻 come off 吐き気を催させるような つづりバラバラ問題 draft すきま風 g u h a t d r 厚板 s b a l おなか y u m m t 適切な r o p r e p 拷問 t t r r e u o あこがれる l n o g どん欲に r e e y l i g d 全体 l w e o h 全体で a h r g o t t l e e 棒 a r b ムシャムシャ食べる u h c m n クリーム状の e y a m r c
- Wendy02
- ベストアンサー率57% (3570/6232)
#4 のコード すみません! もともと、わたし用のために作ったので(^^ゞ '先頭の文字を小文字にするオプション buf = Mid$(buf, 1, Len(buf) - 1) & " " & lastwd ↓ 'buf = Mid$(buf, 1, Len(buf) - 1) & " " & lastwd 'その行を削除するか、「'」シングルクォーテーションを入れてください。 #5 のほうは、改めてアップします。少しお時間ください。簡単ですから、すぐに出来ます。
補足
'その行を削除するか、「'」シングルクォーテーションを入れてください。 この件はわかっていました。 私は の I が i になってしまうのが困っていました。 自分でいろいろやってみるのですが、うまくいきません。 よろしくお願いします。
- Wendy02
- ベストアンサー率57% (3570/6232)
追加です。 Sub RandamPickUpWords() は同じですが、1. の文字並べ替えバージョンを加えました。 しかし、この問題は、さっぱり分かりませんね。 --------------------------- Function rndWord(ar, m) Dim myCol As New Collection Dim arBuf As Variant Dim n As Integer Dim i As Integer, j As Integer, k As Integer Dim myWord As String ReDim arBuf(UBound(ar)) For i = 1 To m myWord = ar(i - 1) Call CheckWord(myWord) myCol.Add myWord Next i Randomize For j = m To 1 Step -1 k = Int(Rnd() * j) + 1 arBuf(n) = myCol.Item(k) myCol.Remove (k) n = n + 1 Next j rndWord = arBuf Erase arBuf End Function Private Sub CheckWord(ByRef mWord As String) '戻り値が同じ文字列を排除するためのサブルーチン Dim a As String If Len(mWord) > 2 Then a = rndChar(mWord) Do While mWord = a a = rndChar(mWord) Loop mWord = a End If End Sub Function rndChar(mWord As String) 'ランダム文字並べ替え Dim buf As String Dim myCol As New Collection Dim n As Integer Dim i As Integer, j As Integer, k As Integer buf = "" n = Len(mWord) If n <= 1 Then rndChar = mWord: Exit Function If n = 2 Then rndChar = Mid$(mWord, 2, 1) & Mid$(mWord, 1, 1): Exit Function For i = 1 To Len(mWord) myCol.Add Mid(mWord, i, 1) Next i Randomize For j = n To 1 Step -1 k = Int(Rnd() * j) + 1 buf = buf & myCol.Item(k) myCol.Remove (k) n = n + 1 Next j rndChar = buf End Function
補足
本当に度々お手数をおかけして申し訳ありません。 質問のしかたがまずかったようです。 文字並べ替えというのは、文章自体はそのままです。 I want to eat an apple. I tanw ot tae na lpepa . 単語の順番はそのままで、文字だけがその中で並び替えます。 上のプログラムから大きく変わるようでしたら結構です。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 >これは元データを本文とピリオド、クエスチョンマークに分離して解決しました。 > china などの大文字だけがネックですが、これは手作業で変換します。 これらは、修正しました。 Webサイトの問題表示自体を、私がアレンジしたわけで、実は、「実際の解いた経験」から考えて作ったのです。いつも("EigoTown.com"で、週に2度ぐらい出てきます)やってきた経験で、「.」が、文字についていないと、その最後尾は非常に難しいと思います。今回は、私の先回りしたアレンジですから、ご質問どおりにしましたので、上書きしてしまってください。 たとえば、こんな文の場合、先頭が、Had なので、これはを、小文字にするわけですが、ピリオド(.) が単語から離れると、これは難しいです。本当は、先頭の文字だけを小文字にすると良いかもしれませんね。 Had I known you were in hospital, I would have visited you. --------------------------------------------- Sub RandamPickUpWords() Dim c As Variant Dim buf As Variant Dim m As Long Dim i As Long, j As Integer Dim arBuf As Variant Dim lastwd As String i = 1 '書き出しの行の初期値 j = 3 '書き出しの列の初期値 For Each c In Range("A1", Range("A65536").End(xlUp)) '2バイト文字除外チェック If VarType(c.Value) = vbString Then buf = StrConv(Trim(c.Value), vbNarrow) '先頭の文字を小文字にするオプション 'buf = StrConv(Mid$(buf, 1, 1), vbLowerCase) & Mid$(buf, 2) If Len(buf) = LenB(StrConv(buf, vbFromUnicode)) Then '修正箇所 If Right(buf, 1) Like "[!-@]" Then lastwd = Right$(buf, 1) buf = Mid$(buf, 1, Len(buf) - 1) & " " & lastwd End If buf = Split(buf, Space(1)) m = UBound(buf) + 1 arBuf = rndWord(buf, m) Cells(i, j).Value = Join(arBuf, Space(1)) i = i + 1 End If End If Next c End Sub Function rndWord(ar, m) Dim myCol As New Collection Dim arBuf As Variant Dim n As Integer Dim i As Integer, j As Integer, k As Integer ReDim arBuf(UBound(ar)) For i = 1 To m myCol.Add ar(i - 1) Next i Randomize For j = m To 1 Step -1 k = Int(Rnd() * j) + 1 arBuf(n) = myCol.Item(k) myCol.Remove (k) n = n + 1 Next j rndWord = arBuf Erase arBuf End Function
補足
わざわざ修正していただきましてありがとうございました。 ピリオド、クエスチョンマークも、大文字も見事に処理できました。 私の I が i に変わるのだけが問題です。これも対処できますでしょうか。 重ね重ねお手数をおかけして申し訳ありません。よろしくお願いします。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 1) は、問題として、見たことがありません。 これは、とりあえず、パスさせてください。 2) これは、以下に出てくるタイプと同じスタイルです。 http://www.eigotown.com/eigocollege/nav.php3?c=2 ピリオドやクエスチョンマークは切り分けはしておりません。 eat an to apple. want i のようなスタイルになります。ExcelのVBE標準モジュールでお使いください。 Sub RandamPickUpWords() Dim c As Variant Dim buf As Variant Dim m As Long Dim i As Long, j As Integer Dim arBuf As Variant i = 1 '書き出しの行の初期値 j = 3 '書き出しの列の初期値 For Each c In Range("A1", Range("A65536").End(xlUp)) '2バイト文字除外チェック If VarType(c.Value) = vbString Then buf = StrConv(Trim(c.Value), vbNarrow) If Len(buf) = LenB(StrConv(buf, vbFromUnicode)) Then buf = Split(buf, Space(1)) m = UBound(buf) + 1 arBuf = rndWord(buf, m) Cells(i, j).Value = Join(arBuf, Space(1)) i = i + 1 End If End If Next c End Sub Function rndWord(ar, m) Dim myCol As New Collection Dim arBuf As Variant Dim n As Integer Dim i As Integer, j As Integer, k As Integer ReDim arBuf(UBound(ar)) For i = 1 To m myCol.Add ar(i - 1) Next i Randomize For j = m To 1 Step -1 k = Int(Rnd() * j) + 1 arBuf(n) = StrConv(myCol.Item(k), vbLowerCase) myCol.Remove (k) n = n + 1 Next j rndWord = arBuf Erase arBuf End Function
お礼
大変お手数をおかけして申し訳ありませんでした。 うまくできたので感心し喜んでおります。 私も昔、Basicでたくさんソフトを作っていたのですが、もう20年もやっていませんので頭がついていきません。関数なら少しわかるので、単語の並び替えで作ったもので、この文章のもやってみたのですが、なかなか解決できませんでした。 >ピリオドやクエスチョンマークは切り分けはしておりません。 これは元データを本文とピリオド、クエスチョンマークに分離して解決しました。 i とか china などの大文字だけがネックですが、これは手作業で変換します。 本当にありがとうございました。
- imogasi
- ベストアンサー率27% (4737/17069)
正しく空白により語の分離が行われておれば、語単位には、Split関数で一発分離可能です。 >英文データがたくさんあります どういうファイル形式というかソフト上でデータがあるのか書いてないのも片手落ちです。エクセルのシートのセルのデータになっているの?ワード、メモ帳(テキスト形式)色々あり、テキストにするまでの難しさが違う。 >ランダムに ご存知だろうが、順列や組み合わせの数は対象となるのもが少し増えると膨大な数になる。それについてはどう考えているの。 文字順を変えた結果意味的に同行とか考えないのかな。 乱数を使ってできるといっても易しくないし。 ーー >VBE作成 エクセルVBAのことをVBEというレベルの方には、ヒントだけでプログラムコードが完成できると思えない。結局他人に丸投げで、回答者に動くコードを作ってくれということになるが、普通のエクセルを事務で使うような(普通のエクセルVBAの課題のような)簡単なものではないし、引き受けられない。 自分で勉強するか、大切なものなら代価を払って業者に頼むしかない。
お礼
ご回答ありがとうございました。 Split関数は初めて知りました。いろいろ試してみます。 ランダムはバラバラという意味で使ってしまい、何度もくり返すわけではないのです。 ご指摘の通り、質問の仕方も内容もVBAのことを余り知らないのに身に過ぎることでした。自分なりにできるところまで努力します。ありがとうございました。
- extrabold
- ベストアンサー率30% (7/23)
簡単に言うと、技術的には可能です。 やり方は書き出すと長いのでポイントだけ。 区切り文字が決まっていれば、Splitという関数を使うことで、文字列を区切り文字単位で区切った文字列配列に変換することが出来ます。関数がなくても自作できますが。 ランダムにするのは、RAND関数があります。これは一様乱数で0から1までの間の小数をランダムに吐き出します。工夫すれば、ランダム選択が出来ます。 単語内の文字を使ってランダムに単語を生成するのも同様にランダム選択で行えばOK。
お礼
回答ありがとうございました。 VBAはあまり自信がありませんが、教えていただいたSplit関数を研究してみます。ありがとうございました。
お礼
早速にご回答、修正していただきありがとうございました。 うまくできました。これで完ぺきです。 >この場合、先頭から2文字のI(大文字のI)+" "(半角スペース)のみになっているものに対しては除外されます。 なるほど、こういう発想をするのかと感心しましたが、関数式の方が私には手が届きません。うまいことできるものですね。 固有名詞が文頭に来る場合は I よりはぐっと稀なので手作業ですればいいです。 乱数の発生だけでも手が込んでいますね。変数と組み合わさっているので難解です。 何日も長時間、お手数をおかけしまして本当にすみませんでした。 特に、私の質問が片手落ちでわかりにくく余計に時間を取らせたことをお詫びします。 英語の勉強がんばります。ありがとうございました。