Excel VBA質問箱 IV

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

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


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

【81441】Re:XMLの名前空間を親ノードで指定すると...
お礼  あも  - 20/8/3(月) 16:44 -

引用なし
パスワード
   ▼γ さん:
そういった仕様ということでことで、納得いたしました。
また、質問掲示板に関するアドバイスもありがとうございます。
・ツリー全体表示

【81440】ジャンプ先を印刷範囲に設定→印刷 のマ...
質問  初心者  - 20/8/3(月) 11:04 -

引用なし
パスワード
   初心者です。よろしくお願い致します。Excelで作成した領収書になります。
【現状】
それぞれの領収書シートに

1行目 1番の氏名 領収日
2行目 2番の氏名 領収日 と、シートによってこの人数は違いますが

例えば、2番の氏名の横の領収日を見て、日付が入っていたら氏名をクリックします。
そうすると、名前の定義された1番のセル範囲(出力したい領収書の範囲)にジャンプします。

ここで、印刷範囲に設定して印刷するところを手作業でやっています。

【希望】
氏名をクリックしてジャンプするところまでは目で確認したいため手動でいいのですが、その部分を印刷範囲に設定して印刷する。また別の氏名をクリックしたら、そこに飛んで印刷する、という作業をボタンで完結させたいと思っています。

ネットからのコピペでいろいろ試してみたのですが、なかなかうまくいかず、
ご相談させていただきました。

よろしくお願い致します。
・ツリー全体表示

【81439】Re:間違いを色であらわすことはできます...
お礼  moro  - 20/8/2(日) 20:08 -

引用なし
パスワード
   ▼γ さん:
数字で試してみたところきちんと動作しました。
修正ありがとうございました。またいろいろ教えて
いただきありがとうございました。


>すべて数値のケースは考慮していませんでした。
>下記の修正を行って、
>書込先のシートの書式を「文字列」にしておけばよいと思います。
>
>Sub main()の
>  '書き込み先のシートをクリアー
>  ws2.UsedRange.Clear
>の下に一行を挿入してください。  
>  ws2.Columns("A:B").NumberFormatLocal = "@"
>
>■なお、相違箇所というものは、ユニークに決まるものではないことに注意が必要です。
>
>どこを共通した箇所と考えるかには、もともと任意性があります。
>例えば、
>ABCBDAB と BDCABA といった比較を考えると、
>(1)
>BCBAが共通部分と考えて、
>ABCBDAB と BDCABA
>~  ~ ~   ~ ~
>が相違点と考えることもできますし、
>(2)
>BDABが共通部分と考えて
>ABCBDAB と BDCABA
>~~~      ~ ~
>が相違点と考えることもできます。
>これらを網羅的に考えるのは別の話になると思います。
>
>■
>現状のもので不都合があれば、ご自分で改善されるか、
>フリーなツールを探されてはいかがでしょうか。
・ツリー全体表示

【81438】Re:間違いを色であらわすことはできます...
回答  γ  - 20/8/2(日) 9:40 -

引用なし
パスワード
   すべて数値のケースは考慮していませんでした。
下記の修正を行って、
書込先のシートの書式を「文字列」にしておけばよいと思います。

Sub main()の
  '書き込み先のシートをクリアー
  ws2.UsedRange.Clear
の下に一行を挿入してください。  
  ws2.Columns("A:B").NumberFormatLocal = "@"

■なお、相違箇所というものは、ユニークに決まるものではないことに注意が必要です。

どこを共通した箇所と考えるかには、もともと任意性があります。
例えば、
ABCBDAB と BDCABA といった比較を考えると、
(1)
BCBAが共通部分と考えて、
ABCBDAB と BDCABA
~  ~ ~   ~ ~
が相違点と考えることもできますし、
(2)
BDABが共通部分と考えて
ABCBDAB と BDCABA
~~~      ~ ~
が相違点と考えることもできます。
これらを網羅的に考えるのは別の話になると思います。


現状のもので不都合があれば、ご自分で改善されるか、
フリーなツールを探されてはいかがでしょうか。
・ツリー全体表示

【81437】Re:間違いを色であらわすことはできます...
回答  moro  - 20/8/1(土) 21:46 -

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

すみません郵便番号や電話番号は大丈夫でしたが

413412 413411 などの数字で試してみたところ数字のみはダメでした。


>>例 〒140-2415 〒142-2315 → 2と3が赤字
>
>失礼ながら、実際に動作させてみたうえでのコメントですか?
>文字列の種類に特段の制限は設けていません。
・ツリー全体表示

【81436】Re:XMLの名前空間を親ノードで指定すると...
発言  γ  - 20/8/1(土) 14:02 -

引用なし
パスワード
   creatNodeは引数にnamespace文字列を必須としていて、
親に <>""のnamespace文字列を指定していたら、
その子に指定したnamespace文字列が、
""であるかどうかに拘わらず出力するというのが仕様なのでしょう。
名前空間を使うなら統一して使う、
ということを暗黙の了解にしているので、それはそれで納得的です。

私も詳細なことを知らないので、別の方法があるのかもしれませんが。

以下、余談:

ここは、ExcelVBAの質問掲示板なので、
この種のテーマを質問するなら、
より広い範囲のテーマも同時に扱う質問掲示板で質問されたほうが
IT実務家の目にも触れ、回答を得られる可能性は高まります。

なにぶん、こちらのサイトは、今や、流量も少ないですし、
管理人さんのメンテナンスも十分されていない印象です。
(URLが変更になっても、その対応がなされず、
 投稿のたびに古いurlを使って再表示してしまい、
 エラーが常に起きます。
 リンクも古いものがリンク切れのまま放置されていますし、
 早晩、収束していくのかなあと、いささか残念に思っています。)
・ツリー全体表示

【81435】Re:表の比較
お礼  T&#8211;K  - 20/8/1(土) 12:29 -

引用なし
パスワード
   送信ありがとうごさいます、
このプラグラムの内容が最初理解できず、
試行錯誤していたため、返信送れました。 
申し訳ありません。
mach関数の処理自体照合処理をして
値を配列に格納していると思いこんでいました。
dictionaryの場合、このような表現も
できるのかなと思いましたが、


配列ではindex番号でしか表現する方法
を知らないためw(my.mx)が?となっていました。
マッチ関数の結果が位置を出すものと知ってからは
処理の意味がわかりました。勉強不足ということです。
とりあえす利用ささて頂き高速になりました
感謝いたします。
・ツリー全体表示

【81434】Re:表の比較
発言  マナ  - 20/7/30(木) 20:20 -

引用なし
パスワード
   ▼T-K さん:

>Dictionaryを使ってのコード提示ありがとうございます。

どちらかというと配列のコードのつもりだったのですが…


Sub test3()
  Dim fSh As Worksheet
  Dim tSh As Worksheet
  Dim tbl As Range
  Dim i As Long, k As Long
  Dim dt As Double
  Dim com As String
  Dim mX, mY
  Dim w
  Dim flg As Boolean

  Set fSh = Sheets("Sheet1")
  Set tSh = Sheets("Sheet2")

  fSh.Cells.Interior.ColorIndex = xlNone
 
  Set tbl = tSh.Range("A1").CurrentRegion
  w = tbl.Value

  With fSh.Range("A1").CurrentRegion
    For i = 2 To .Rows.Count
      com = .Cells(i, "B").Value
      mY = Application.Match(com, tbl.Columns("B"), 0)
      If IsError(mY) Then
        .Rows(i).Interior.ColorIndex = 3
      Else
        For k = 3 To .Columns.Count
          dt = .Cells(1, k).Value2
          mX = Application.Match(dt, tbl.Rows(1), 0)
          If IsError(mX) Then
            If Not flg Then .Columns(k).Interior.ColorIndex = 3
          Else
            w(mY, mX) = .Cells(i, k).Value
          End If
        Next
        flg = True
      End If
    Next
  End With
 
  tbl.Value = w

End Sub
・ツリー全体表示

【81433】Re:表の比較
発言  マナ  - 20/7/30(木) 19:30 -

引用なし
パスワード
   ▼T-K さん:

>今回の目的は質問にかいたように配列を理解することと、

配列を使った一括書き込みを理解するには、
最初にも書きましたが、もっと単純な例がよいです。

www.vbalab.sakura.ne.jp/vbaqa/c-board.cgi?cmd=ntr;tree=81369;id=excel

例えば、↑これは理解できていますか。
・ツリー全体表示

【81432】XMLの名前空間を親ノードで指定すると、...
質問  あも  - 20/7/30(木) 18:37 -

引用なし
パスワード
   XMLの名前空間を親ノードで指定すると、子ノードにxmlns=""と自動的に入力されてしまいます。
testノードにはxmlns=""を出力させたくないのですが、方法はありますか?

□出力結果
<root xmlns="aaa.co.jp>
 <test xmlns=""/>
</root>

□理想の結果
<root xmlns="aaa.co.jp">
 <test/>
</root>

□現在のコード
Sub Samples()
Dim xmlDoc As MSXML2.DOMDocument60
Dim xmlPI As IXMLDOMProcessingInstruction 'XML宣言
Dim rootelement As MSXML2.IXMLDOMElement
Dim element As MSXML2.IXMLDOMElement


'XMLドキュメント作成
Set xmlDoc = Nothing
Set xmlDoc = New MSXML2.DOMDocument60
'XML宣言
Set xmlPI = xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", "version=""1.0"" encoding=""UTF-8"""))

Set rootelement = xmlDoc.createElement("root")
xmlDoc.appendChild rootelement
Set attr = xmlDoc.createNode(2, "xmlns", "")
attr.Text = "aaa.co.jp"
rootelement.setAttributeNode attr

Set element = rootelement.appendChild(xmlDoc.createNode(NODE_ELEMENT, "test", ""))

xmlDoc.Save ("namespace.xml")
End Sub
・ツリー全体表示

【81431】Re:間違いを色であらわすことはできます...
回答  γ  - 20/7/30(木) 8:00 -

引用なし
パスワード
   >例 〒140-2415 〒142-2315 → 2と3が赤字

失礼ながら、実際に動作させてみたうえでのコメントですか?
文字列の種類に特段の制限は設けていません。
・ツリー全体表示

【81430】Re:複数の値からある合計に一致するすべ...
発言  γ  - 20/7/29(水) 23:51 -

引用なし
パスワード
   参考サイトの記事のなかでも紹介されていますが、
hatenaさん作成になるこちらの記事が参考になると思います。
 ht tps://hatenachips.blog.fc2.com/blog-entry-430.html

アルゴリズムの説明のほか、実際に動作するxlsmファイルも
提供されていますので、試行することができます。
・ツリー全体表示

【81429】Re:表の比較
発言  T-K  - 20/7/29(水) 23:31 -

引用なし
パスワード
   返信ありがとうございます
Dictionaryを使ってのコード提示ありがとうございます。
シートに一度に書き込んでいるのは、コードをみて何となく理解できるのですが、
自分で応用ができないのが現状です。
いままでなら、このコードを少し変更して利用していますが、
今回の目的は質問にかいたように配列を理解することと、配列でDictionaryと同じ 表現ができるのかが課題です。
あと自分で作った物も無駄にしたくないため、どこを直せばいいのかを知りたいです


配列でもテーブル範囲を指定すれば一括で記入は可能なようですが、
Splitで区切った物を配列に入れたため複雑な構造になっていてうまくいきません

作っても”型が合いません”&"インデックスが有効範囲にありません"とエラーがでてしまっています。
もしわかるようであればおしえてください
よろしくお願いします。
・ツリー全体表示

【81428】Re:複数の値からある合計に一致するすべ...
発言  マナ  - 20/7/29(水) 20:10 -

引用なし
パスワード
   ▼ゆきぼ さん:

>確かに最終回答者様のコードで試してみると、結果は出るのですが
>「max=19」であれば問題なしでした。
>ですが使いたい数字は0〜36までなのです。
>試しに「max=20」で回答が表示されるまでに5分。
>「max=25」だと30分待っても答えが出ませんでした(カーソルがくるくる状態)
>組み合わせが多くなるからでしょうか?


そうだと思います。

>であれば、もっと簡単な方法はないものでしょうか?

現在の方法は、総当たりなので効率は悪そうですが
何となくしか、理解できていないので
わたしには、わかりません。

海外サイトも含めて、検索してみては、どうでしょうか。
・ツリー全体表示

【81426】Re:複数の値からある合計に一致するすべ...
質問  ゆきぼ  - 20/7/29(水) 13:15 -

引用なし
パスワード
   ▼マナ さん:
>▼ゆきぼ さん:
>
>>こちらのサイトは私も参考にして試してみたのですが
>>動かないか、思うような答えが出ないかのどちらかでした。
>>
>
>わたしが試したのは、最後の回答者のコードだけですが
>期待通りの結果になりましたが…

検証ありがとうございます。
確かに最終回答者様のコードで試してみると、結果は出るのですが
「max=19」であれば問題なしでした。
ですが使いたい数字は0〜36までなのです。
試しに「max=20」で回答が表示されるまでに5分。
「max=25」だと30分待っても答えが出ませんでした(カーソルがくるくる状態)
組み合わせが多くなるからでしょうか?
であれば、もっと簡単な方法はないものでしょうか?
・ツリー全体表示

【81425】Re:間違いを色であらわすことはできます...
質問  tatu  - 20/7/29(水) 12:41 -

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

試しにやってみましたが、きちんと動作しました。ありがとうございます。
もし可能であれば、数字や記号にも対応できるものであればありがたいので
すが、よろしくお願いいたします。

例 〒140-2415 〒142-2315 → 2と3が赤字


>最長共通部分列(longest common subsequence)問題という
>比較的良く知られた問題らしいです。
>(文章の差異を表示するDiffコマンドというものも同じアルゴリズムの系列です。)
>
>大昔、こちらの掲示板に投稿したものの一部を修正(表示の一部を削除)したものです。
>参考にしてください。
>
>Sheet1のA列とB列を比較した結果を、
>Sheet2のA列とB列に表示します。(不一致箇所を赤文字かつアンダーラインで表示)
>
>Option Explicit
>
>Dim lcs() As Long
>Dim dic1 As Object
>Dim dic2 As Object
>Dim s1 As String
>Dim s2 As String
>Dim ws1 As Worksheet
>Dim ws2 As Worksheet
>
>Sub main()
>  Dim k As Long
>
>  Set ws1 = Worksheets("Sheet1")
>  Set ws2 = Worksheets("Sheet2")
>
>  '書き込み先のシートをクリアー
>  ws2.UsedRange.Clear
>
>  'A列とB列の差異を調べて結果をSheet2に表示する
>  For k = 1 To ws1.Cells(ws1.Cells.Rows.Count, 1).End(xlUp).Row
>    diff ws1.Cells(k, 1), ws1.Cells(k, 2)
>  Next
>End Sub
>
>Sub diff(r1 As Range, r2 As Range)
>  Dim ar1, ar2
>  Dim v
>  Dim pos As Long
>  Dim kk As Long
>
>  Set dic1 = CreateObject("Scripting.Dictionary")
>  Set dic2 = CreateObject("Scripting.Dictionary")
>
>  ' 二つの文字列のLCSの長さを求める
>  get_lcs r1, r2
>
>  'それに対応する最長共通部分列を求める
>  get_lcs_string r1.Value, r2.Value
>
>  '結果をSheet2に書き込む
>  pos = Application.Max(ws2.Cells(ws2.Rows.Count, 1).End(xlUp).Row, _
>             ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row) _
>             + 1
>  ws2.Cells(pos, 1) = s1
>  ws2.Cells(pos, 2) = s2
>
>  '最長共通部分列に該当しない文字列に、書式を設定(赤、アンダーライン)
>  setColor ws2.Cells(pos, 1), ws2.Cells(pos, 2)
>End Sub
>
>Function get_lcs(r1 As Range, r2 As Range)
>  Dim j As Long, k As Long
>
>  s1 = r1.Value
>  s2 = r2.Value
>  ' lcs(j,k) は s1の1からjまでの部分列と
>  '       s2の1からkまでの部分列との
>  '       LCSの長さを示す
>  ReDim lcs(0 To Len(s1), 0 To Len(s2))
>  For j = 1 To Len(s1)
>    For k = 1 To Len(s2)
>      If Mid(s1, j, 1) = Mid(s2, k, 1) Then
>        lcs(j, k) = lcs(j - 1, k - 1) + 1
>      Else
>        lcs(j, k) = WorksheetFunction.Max(lcs(j, k - 1), lcs(j - 1, k))
>      End If
>    Next
>  Next
>End Function
>
>Function get_lcs_string(s1 As String, s2 As String)
>  get_lcs_string_sub Len(s1), Len(s2)
>End Function
>
>Function get_lcs_string_sub(j As Long, k As Long)
>  If j = 0 Or k = 0 Then Exit Function
>  If Mid(s1, j, 1) = Mid(s2, k, 1) Then
>    Call get_lcs_string_sub(j - 1, k - 1)
>    dic1(j) = Empty   's1 の j番目の文字がLCSを構成
>    dic2(k) = Empty   's2 の k番目の文字がLCSを構成
>  Else
>    If lcs(j - 1, k) >= lcs(j, k - 1) Then
>      Call get_lcs_string_sub(j - 1, k)
>    Else
>      Call get_lcs_string_sub(j, k - 1)
>    End If
>  End If
>End Function
>
>Function get_partition(s As String, d As Object) As Variant
>  Dim key
>
>  For Each key In d.keys
>    Mid$(s, key, 1) = "_"  ' 余り使用されない文字の意
>  Next
>  get_partition = Split(s, "_")
>End Function
>
>Function setColor(r1 As Range, r2 As Range)
>  Dim j As Long, k As Long
>
>  '背景色を水色
>  r1.Interior.ColorIndex = 34
>  r2.Interior.ColorIndex = 34
>
>  'マッチしない文字列の文字色を赤に
>  For j = 1 To Len(r1.Value)
>    If Not dic1.exists(j) Then
>      With r1.Characters(Start:=j, Length:=1).Font
>        .Underline = xlUnderlineStyleSingle
>        .ColorIndex = 3
>      End With
>    End If
>  Next
>
>  For k = 1 To Len(r2.Value)
>    If Not dic2.exists(k) Then
>      With r2.Characters(Start:=k, Length:=1).Font
>        .Underline = xlUnderlineStyleSingle
>        .ColorIndex = 3
>      End With
>    End If
>  Next
>End Function
・ツリー全体表示

【81424】Re:間違いを色であらわすことはできます...
お礼  [名前なし]  - 20/7/28(火) 12:40 -

引用なし
パスワード
   ありがとうございます。これで試してみます!

▼γ さん:
>最長共通部分列(longest common subsequence)問題という
>比較的良く知られた問題らしいです。
>(文章の差異を表示するDiffコマンドというものも同じアルゴリズムの系列です。)
>
>大昔、こちらの掲示板に投稿したものの一部を修正(表示の一部を削除)したものです。
>参考にしてください。
>
>Sheet1のA列とB列を比較した結果を、
>Sheet2のA列とB列に表示します。(不一致箇所を赤文字かつアンダーラインで表示)
>
>Option Explicit
>
>Dim lcs() As Long
>Dim dic1 As Object
>Dim dic2 As Object
>Dim s1 As String
>Dim s2 As String
>Dim ws1 As Worksheet
>Dim ws2 As Worksheet
>
>Sub main()
>  Dim k As Long
>
>  Set ws1 = Worksheets("Sheet1")
>  Set ws2 = Worksheets("Sheet2")
>
>  '書き込み先のシートをクリアー
>  ws2.UsedRange.Clear
>
>  'A列とB列の差異を調べて結果をSheet2に表示する
>  For k = 1 To ws1.Cells(ws1.Cells.Rows.Count, 1).End(xlUp).Row
>    diff ws1.Cells(k, 1), ws1.Cells(k, 2)
>  Next
>End Sub
>
>Sub diff(r1 As Range, r2 As Range)
>  Dim ar1, ar2
>  Dim v
>  Dim pos As Long
>  Dim kk As Long
>
>  Set dic1 = CreateObject("Scripting.Dictionary")
>  Set dic2 = CreateObject("Scripting.Dictionary")
>
>  ' 二つの文字列のLCSの長さを求める
>  get_lcs r1, r2
>
>  'それに対応する最長共通部分列を求める
>  get_lcs_string r1.Value, r2.Value
>
>  '結果をSheet2に書き込む
>  pos = Application.Max(ws2.Cells(ws2.Rows.Count, 1).End(xlUp).Row, _
>             ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row) _
>             + 1
>  ws2.Cells(pos, 1) = s1
>  ws2.Cells(pos, 2) = s2
>
>  '最長共通部分列に該当しない文字列に、書式を設定(赤、アンダーライン)
>  setColor ws2.Cells(pos, 1), ws2.Cells(pos, 2)
>End Sub
>
>Function get_lcs(r1 As Range, r2 As Range)
>  Dim j As Long, k As Long
>
>  s1 = r1.Value
>  s2 = r2.Value
>  ' lcs(j,k) は s1の1からjまでの部分列と
>  '       s2の1からkまでの部分列との
>  '       LCSの長さを示す
>  ReDim lcs(0 To Len(s1), 0 To Len(s2))
>  For j = 1 To Len(s1)
>    For k = 1 To Len(s2)
>      If Mid(s1, j, 1) = Mid(s2, k, 1) Then
>        lcs(j, k) = lcs(j - 1, k - 1) + 1
>      Else
>        lcs(j, k) = WorksheetFunction.Max(lcs(j, k - 1), lcs(j - 1, k))
>      End If
>    Next
>  Next
>End Function
>
>Function get_lcs_string(s1 As String, s2 As String)
>  get_lcs_string_sub Len(s1), Len(s2)
>End Function
>
>Function get_lcs_string_sub(j As Long, k As Long)
>  If j = 0 Or k = 0 Then Exit Function
>  If Mid(s1, j, 1) = Mid(s2, k, 1) Then
>    Call get_lcs_string_sub(j - 1, k - 1)
>    dic1(j) = Empty   's1 の j番目の文字がLCSを構成
>    dic2(k) = Empty   's2 の k番目の文字がLCSを構成
>  Else
>    If lcs(j - 1, k) >= lcs(j, k - 1) Then
>      Call get_lcs_string_sub(j - 1, k)
>    Else
>      Call get_lcs_string_sub(j, k - 1)
>    End If
>  End If
>End Function
>
>Function get_partition(s As String, d As Object) As Variant
>  Dim key
>
>  For Each key In d.keys
>    Mid$(s, key, 1) = "_"  ' 余り使用されない文字の意
>  Next
>  get_partition = Split(s, "_")
>End Function
>
>Function setColor(r1 As Range, r2 As Range)
>  Dim j As Long, k As Long
>
>  '背景色を水色
>  r1.Interior.ColorIndex = 34
>  r2.Interior.ColorIndex = 34
>
>  'マッチしない文字列の文字色を赤に
>  For j = 1 To Len(r1.Value)
>    If Not dic1.exists(j) Then
>      With r1.Characters(Start:=j, Length:=1).Font
>        .Underline = xlUnderlineStyleSingle
>        .ColorIndex = 3
>      End With
>    End If
>  Next
>
>  For k = 1 To Len(r2.Value)
>    If Not dic2.exists(k) Then
>      With r2.Characters(Start:=k, Length:=1).Font
>        .Underline = xlUnderlineStyleSingle
>        .ColorIndex = 3
>      End With
>    End If
>  Next
>End Function
・ツリー全体表示

【81423】Re:間違いを色であらわすことはできます...
回答  [名前なし]  - 20/7/28(火) 12:38 -

引用なし
パスワード
   ▼γ さん:
>両者の不一致文字列を赤く着色するのではまずいですか?
>山梨市  山梨  → 左の市だけを赤くする。

それでも大丈夫です。
・ツリー全体表示

【81422】Re:間違いを色であらわすことはできます...
回答  γ  - 20/7/27(月) 6:06 -

引用なし
パスワード
   最長共通部分列(longest common subsequence)問題という
比較的良く知られた問題らしいです。
(文章の差異を表示するDiffコマンドというものも同じアルゴリズムの系列です。)

大昔、こちらの掲示板に投稿したものの一部を修正(表示の一部を削除)したものです。
参考にしてください。

Sheet1のA列とB列を比較した結果を、
Sheet2のA列とB列に表示します。(不一致箇所を赤文字かつアンダーラインで表示)

Option Explicit

Dim lcs() As Long
Dim dic1 As Object
Dim dic2 As Object
Dim s1 As String
Dim s2 As String
Dim ws1 As Worksheet
Dim ws2 As Worksheet

Sub main()
  Dim k As Long

  Set ws1 = Worksheets("Sheet1")
  Set ws2 = Worksheets("Sheet2")

  '書き込み先のシートをクリアー
  ws2.UsedRange.Clear

  'A列とB列の差異を調べて結果をSheet2に表示する
  For k = 1 To ws1.Cells(ws1.Cells.Rows.Count, 1).End(xlUp).Row
    diff ws1.Cells(k, 1), ws1.Cells(k, 2)
  Next
End Sub

Sub diff(r1 As Range, r2 As Range)
  Dim ar1, ar2
  Dim v
  Dim pos As Long
  Dim kk As Long

  Set dic1 = CreateObject("Scripting.Dictionary")
  Set dic2 = CreateObject("Scripting.Dictionary")

  ' 二つの文字列のLCSの長さを求める
  get_lcs r1, r2

  'それに対応する最長共通部分列を求める
  get_lcs_string r1.Value, r2.Value

  '結果をSheet2に書き込む
  pos = Application.Max(ws2.Cells(ws2.Rows.Count, 1).End(xlUp).Row, _
             ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row) _
             + 1
  ws2.Cells(pos, 1) = s1
  ws2.Cells(pos, 2) = s2

  '最長共通部分列に該当しない文字列に、書式を設定(赤、アンダーライン)
  setColor ws2.Cells(pos, 1), ws2.Cells(pos, 2)
End Sub

Function get_lcs(r1 As Range, r2 As Range)
  Dim j As Long, k As Long

  s1 = r1.Value
  s2 = r2.Value
  ' lcs(j,k) は s1の1からjまでの部分列と
  '       s2の1からkまでの部分列との
  '       LCSの長さを示す
  ReDim lcs(0 To Len(s1), 0 To Len(s2))
  For j = 1 To Len(s1)
    For k = 1 To Len(s2)
      If Mid(s1, j, 1) = Mid(s2, k, 1) Then
        lcs(j, k) = lcs(j - 1, k - 1) + 1
      Else
        lcs(j, k) = WorksheetFunction.Max(lcs(j, k - 1), lcs(j - 1, k))
      End If
    Next
  Next
End Function

Function get_lcs_string(s1 As String, s2 As String)
  get_lcs_string_sub Len(s1), Len(s2)
End Function

Function get_lcs_string_sub(j As Long, k As Long)
  If j = 0 Or k = 0 Then Exit Function
  If Mid(s1, j, 1) = Mid(s2, k, 1) Then
    Call get_lcs_string_sub(j - 1, k - 1)
    dic1(j) = Empty   's1 の j番目の文字がLCSを構成
    dic2(k) = Empty   's2 の k番目の文字がLCSを構成
  Else
    If lcs(j - 1, k) >= lcs(j, k - 1) Then
      Call get_lcs_string_sub(j - 1, k)
    Else
      Call get_lcs_string_sub(j, k - 1)
    End If
  End If
End Function

Function get_partition(s As String, d As Object) As Variant
  Dim key

  For Each key In d.keys
    Mid$(s, key, 1) = "_"  ' 余り使用されない文字の意
  Next
  get_partition = Split(s, "_")
End Function

Function setColor(r1 As Range, r2 As Range)
  Dim j As Long, k As Long

  '背景色を水色
  r1.Interior.ColorIndex = 34
  r2.Interior.ColorIndex = 34

  'マッチしない文字列の文字色を赤に
  For j = 1 To Len(r1.Value)
    If Not dic1.exists(j) Then
      With r1.Characters(Start:=j, Length:=1).Font
        .Underline = xlUnderlineStyleSingle
        .ColorIndex = 3
      End With
    End If
  Next

  For k = 1 To Len(r2.Value)
    If Not dic2.exists(k) Then
      With r2.Characters(Start:=k, Length:=1).Font
        .Underline = xlUnderlineStyleSingle
        .ColorIndex = 3
      End With
    End If
  Next
End Function
・ツリー全体表示

【81421】Re:表を加工して別シートに転記したい
お礼  ありす  - 20/7/27(月) 0:15 -

引用なし
パスワード
   ▼マナ さん:
ありがとうございました。
前述の修正と以下に頂いたものを確認しながら、勉強してみます。
品名の後ろの年月、すっかり忘れてました笑
これ重要だったのに。
ソートの部分も、ごちゃごちゃ書かずにすっきりできたので、
変数の部分と合わせて確認しながら書いてみます。

>▼ありす さん:
>
>こんな書き方もできます
>マクロで、Noを作成し、最後に削除しています。
>
>>・最後に並べ替えをする際に、コードが被る事があるので、C列に並べ替え用Noを入れる項目を追加。
>

>
>Option Explicit
>
>Sub test()
>  Dim wsF As Worksheet, wsT As Worksheet
>  Dim 期間 As Long, 開始日 As Date
>  Dim 元データ As Range, データ数 As Long
>  Dim 貼付先 As Range
>  Dim k As Long, 月末 As Date
>  Dim 商品名 As Range, 数式 As String
>  Dim ソート範囲 As Range
>
>  Set wsF = Worksheets("Sheet1")
>  Set wsT = Worksheets("Sheet2") '転記先
>  
>  期間 = wsF.Range("B5").Value
>  開始日 = wsF.Range("B6").Value
>  
>  Set 元データ = wsF.Range("C6", wsF.Range("K" & Rows.Count).End(xlUp))
>  元データ.Columns(1).Formula = "=row()"  '並べ替え用No
>  データ数 = 元データ.Rows.Count
>  
>  Set 貼付先 = wsT.Range("C6")
>   
>  For k = 1 To 期間
>'  'sheet1のデータをsheet2に貼り付け
>    元データ.Copy
>    貼付先.PasteSpecial xlPasteValues
>
>    '日付の入力
>    月末 = DateSerial(Year(開始日), Month(開始日) + k, 0)
>    貼付先.Resize(データ数).Columns(2).Value = 月末
>    
>    '商品名に日付を付加
>    Set 商品名 = 貼付先.Resize(データ数).Columns(7)
>    数式 = 商品名.Address & "&""" & Format(月末, "('yy/m月分)") & """"
>    商品名.Value = 商品名.Worksheet.Evaluate(数式)
>    
>    Set 貼付先 = 貼付先.Offset(データ数)
>  Next
>  
>  '並べ替え
>  Set ソート範囲 = wsT.Range("C6", wsT.Range("K" & Rows.Count).End(xlUp))
>  ソート範囲.Sort ソート範囲.Columns(1)
>  
>  '並べ替え用Noの削除
>  ソート範囲.Columns(1).ClearContents
>  元データ.Columns(1).ClearContents
>    
>End Sub
>
>
>
・ツリー全体表示

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