Kの備忘録(仮)

Python、VBA、Excelを中心に記事を投稿

VBA配列とEnumステートメントの活用1

はじめに

私はEnumステートメントが大好きです!なぜならコードの可読性が上がるので便利だからです。

Enumステートメントを使うと定数をまとめて定義できます。これが配列と相性がいいので、よく一緒に使います。

今回はその一例を紹介します。

今回用意したデータ

e-Statで公開されている2020年の国税調査結果の「人口速報集計(男女別人口及び世帯総数)」を使用します。

https://www.e-stat.go.jp/stat-search/files?page=1&layout=datalist&toukei=00200521&tstat=000001136464&cycle=0&tclass1=000001136465&tclass2=000001154388&tclass3val=0

ダウンロードしたファイルを確認します。 f:id:lbibouroku:20220219224129p:plain

このままでは、ちょっとVBAの配列が使いにくいですね・・・。なので手を加えて以下のように加工しました。 f:id:lbibouroku:20220219224242p:plain

ちなみに、このブックのシートは、もともとあった「a01」と、今回転記用に使用する「都道府県別総人口」を追加した2シートです。 f:id:lbibouroku:20220219230909p:plain

今回やりたい処理

では、このデータを使用してEnumステートメントと配列を活用して実施する内容を決めます。

まずはざっくり、こんな感じで決めてみました。

「a01」シートから全国と各都道府県の総人口情報を収集して、必要な項目のみ「都道府県別総人口」シートへ転記する

このままでは抽象的なので、具体的に条件を決めていきます。

地域識別コードを調べてみると、総数の情報は「地域識別コード:a」のようですね。よって「地域識別コードが「a」の項目を転記対象とする」という条件ができました。

また、転記する項目は以下7項目としましょう。

  • 地域識別コード
  • 都道府県
  • 人口/総数
  • 人口/男
  • 人口/女
  • 人口密度
  • 世帯数

まとめると以下の処理になります。

「a01」シートの「地域識別コードが「a」の項目かつ、上記7項目のみ「都道府県別総人口」シートへ転記する

さて、やりたいことが決まったところで、 Enumステートメントの定義内容を決めます。

Enumステートメントの定義内容

まずはEnumステートメントで定義したいグループ名を決めます。

今回は「「a01」シート1行目の項目名」を対象にします。

よって、Enumステートメントのグループ名は「a01シート項目」とします。

では、グループの各要素名を決めましょう。

「a01」シート1行目の項目名は以下の16個です。

  • 地域識別コード
  • 都道府県
  • 地域名
  • 人口/総数
  • 人口/男
  • 人口/女
  • 2015年(平成27年)の人口(組替)
  • 5年間の人口増減数
  • 5年間の人口増減率
  • 人口性比
  • 面積(参考)
  • 人口密度
  • 世帯数
  • 2015年(平成27年)の世帯数(組替)
  • 5年間の世帯増減数
  • 5年間の世帯増減率

さて、ここで注意点があります。

VBAでは変数名や、Enumステートメントのグループ名や要素名などには、命名ルールがあります。

Office TANAKAさんのサイトからVBAの変数の命名の注意点を引用します。 http://officetanaka.net/excel/vba/variable/06.htm

  1. 変数名には文字(日本語を含む)のほか、アンダーバー(_)だけを使えて、そのほかの記号やスペースは使えない
  2. 変数名の先頭が数字やアンダーバー(_)ではいけない
  3. 同じ適用範囲で同じ名前は使えない
  4. 変数名の長さは半角で255文字まで

Enumステートメントのグループ要素も同じ命名ルールです。よって、少し工夫して今回は以下のEnumステートメントのグループの要素名で定義します。

  • 地域識別コード
  • 都道府県
  • 地域名
  • 人口_総数
  • 人口_男
  • 人口_女
  • 人口_2015年
  • 過去5年間の人口増減数
  • 過去5年間の人口増減率
  • 人口性比
  • 面積_参考
  • 人口密度
  • 世帯数
  • 世帯数_2015年
  • 過去5年間の世帯増減数
  • 過去5年間の世帯増減率

Enumステートメントの定義内容が決まったところでコードを書きたいのですが、長くなってしまったので一旦ここで区切ります。

2022年の目標-学習編-

はじめに

みなさま、あけましておめでとうございます。今年もよろしくお願いします!

さて、昨年末に2022年の抱負を建てました。 内容はこんな感じです。

  • Pythonの世界を広げる
  • 料理を作るモチベーションを上げて健康的な食生活を送る
  • ライブにいっぱい行く

1年を通してゆるっと達成できれば位に思って決めた抱負ですが、学習面についてもう少し具体的に計画を立てたいなって思ったので、まとめてみます。

◆目次◆

技術ライティング

去年のうちに技術書典へ向けての執筆も終ったので、今年はノウハウの蓄積と技術ブログの執筆に力入れたいなって思います。

ノウハウ蓄積はNotionを使う予定です。なので、自分が見やすいようなNotionの設計を現在考え中です。この辺の設計は苦手です・・・。

でもここで詰まってたら他の学習も進まないので、とりあえず走り出すのでいいかなと思ってます(後から変えられるし)。

やることリスト

  • 技術ライティングについて復習する
  • Notionでノウハウの蓄積・管理をする
  • 蓄積したノウハウをきれいに整えて技術ブログで公開する

Python

今年一番力を入れたいところです!

ちゃんとリーダブルなコード書けるようになりたいし、他のサービス(主にGoogle関連)と連携もできるようになりたい。

あと、個人的に分析とか機械学習も勉強したいです。

やることリスト

20本ノック→「Python実践データ分析100本ノック」のうち、最初の20本をたまにリファクタリングしてみて、自分の成長を計りたいなって思ってます。

データ分析系

仕事でデータを扱うので、データサイエンスや統計の分野も勉強したいです。

結構読みたい本は決まっているので、読んで自分なりに要約したり、ExcelPythonで実践したりして理解していきたいな。あと、この辺の分野についていろんな人と話をしたいです。

やることリスト

Google Workspace

これも仕事で使います。スプレッドシート関数は少し調べたけどExcel関数と同じものも多数ある印象。

ここは楽しみながらできそう!

やることリスト

おわりに

あれ、やることいっぱいある・・・。できるのか?

まずは、3か月くらい強化月間としてがんばります。時々、振り返りブログで状況を記録したいですね。

2021年振り返り

はじめに

2021年も残すところ2週間、早いものですね。

今年は割とやり残したことはないように思います。なんかいろいろあったなあ・・・。手帳と私の記憶を頼りにしつつ、ノンプロ研の活動を中心にちょっと振り返ってみます。

本記事は私の所属しているコミュニティ、ノンプログラマーのためのスキルアップ研究会の『ノンプロ研 Advent Calendar 2021』 17日目の記事です。

adventar.org

ノンプロ研入会

VBAを独学してましたが、2020年から壁にぶつかってました。周りに相談できる人もいなかったので、モチベーションも下がってきてだいぶ煮詰まってましたね。

一人で悩んでも解決しないなと、思い切って2021年2月にノンプロ研に入会しました。

入会前はVBAの入口当たりが私の知っているプログラミングの世界でしたが、入会後は、PythonVBAの知らなかった部分やプログラミング以外のことも知る機会を経て世界が広がった感じです!

このコミュニティを見つけた私は運がいいですw

VBA

ノンプロ研入会前もある程度想定した動きをするマクロは作れていました。しかし動きが複雑なものになると保守性が低く、動きもフリーズしそうなマクロになってしまいどうしたらいいのか悩んでいました。

VBA中級講座を受講し、今まで書けなかったコードが書けるようになりました!リファクタリングもできたし、おそらく大きな壁を一つ乗り越えられたので、満足です。

オブジェクトブラウザとオブジェクトモジュールが使えるようになったのも、この講座のおかげです。

Python

これも前に独学で即挫折していました。あと、何に使うのかもよくわかっていなかったです。

Python初級講座を受講し簡単なツールが作れるようになりました。講座のティーチングアシスタントをさせていただくことにもなって・・・人生何があるかわかりませんね。

これからはデータ分析とか機械学習の方向を学んでいきたいなと思っています。

技術ライティング

技術ライティング講座を受講し、技術ブログが書けるようになりました。あと、Twitterも活用できるようになったのかな。Git&githubもちょっと使えるようになりました!

仕事でも、文章の書き方をより考えるようになったので、ノンプロ研の中では一番コスパがいい講座だと思います(課題はしんどいけど)。

そして、技術書典に技術本を出典することになりました・・・。

Excel VBA配列入門

これは、技術書典に出す本のタイトルです。

正直、企画書提出時はそんなに配列のことわかってなかったし嫌いでした。なので、同じようにVBA配列の学習に苦労している人もいると思うので「需要はあるかも」と思ってこの題材にしました。そろそろ、VBA配列についてまとめた本が出来そうです(12/16現在、終わりは見えてきました)。

たぶん、4か月くらい配列のことを考え続けてきましたが、ようやくそんな日々も終わりそうです!

監修のタカハシさんをはじめ、アドバイスをくれた方々、応援してくれた方々のおかげで1冊の本の形になったので、みなさんには感謝しかないです。ありがとうございました!

ノンプロ研以外

いろいろありましたが、ここに書ける範囲だとカンピロバクターに感染したのが今年の事件でした。 ほんとに辛くて、3日間寝込みました。あれから鶏肉は良く焼くようになりましたw

総括

総じて楽しい1年でした。やはりノンプロ研入会は大きな転機だったと思います。

手帳を見たら今年は仕事の面では辛いことが結構あったようですが、7割くらい忘れていたので我ながら得な性分だなと思います。

結果、今が一番楽しいし、未来は明るいです。

来年の抱負

せっかくなので、来年の抱負を3つあげます。

  • Pythonの世界を広げる
  • 料理を作るモチベーションを上げて健康的な食生活を送る
  • ライブにいっぱい行く

さいごに

なんだか日記のような内容になってしまいましたが、ここまで読んでいただいてありがとうございます。みなさん良いお年をお迎えください。

それでは、みやさんにAdvent Calendarのバトンを渡します!

みやさん、よろしくお願いします('ω')ノ

Pythonのリストの加算と乗算の検証

はじめに

Pythonのリストでは、リスト同士の加算または乗算で要素の追加が可能です。

では、加算または乗算するとどうなるのか、検証したいと思います。

なお、Pythonではリスト同士の減算と除算はPythonではサポートしていません。試したところ、以下のエラーが出ました。

TypeError: unsupported operand type(s) for -: 'list' and 'list'

直訳: -: 'list'および 'list'のサポートされていないオペランドタイプ

ますは、リストの基本をおさらいします。

リストとは

データの集合で、変更可能かつ、順序がある反復可能なデータ型です。

リストの生成

リストを生成するには、以下のとおり変数に値を代入します。

変数 = [要素1, 要素2, 要素3, ・・・]

例)

list_a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

print(list_a)

出力結果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

では、基本をおさらいしたところで、さっそく検証してみましょう。

1次元リストの検証

1次元リスト同士でリストを加算

list_a = [1, 2]
list_b = [3, 4]

print(list_a + list_b)

出力結果:[1, 2, 3, 4]

単純に要素が追加されて、2つの1次元リストが1つになりました。

では、累算代入演算子を使って加算するとどうなるでしょうか。

list_a = [1, 2]
list_b = [3, 4]

list_a += list_b

print(list_a)

出力結果:[1, 2, 3, 4]

変数list_aに変数list_bの要素が追加されました。

1次元リストを乗算

list_a = [1, 2]*2

print(list_a)

出力結果:[1, 2, 1, 2]

変数list_aの要素が繰り返され、要素数が2倍になりました。

1次元リストの検証結果

加算または乗算することで、1次元リストの要素数が増えます。

2次元リストの検証

2次元リスト同士でリストを加算

list_a = [[1, 2]]
list_b = [[3, 4]]

print(list_a + list_b)

出力結果:[[1, 2], [3, 4]]

単純に要素が追加されて、2つの2次元リストが1つになりました。

では、累算代入演算子を使って加算するとどうなるでしょうか。

list_a = [[1, 2]]
list_b = [[3, 4]]

list_a += list_b

print(list_a)

出力結果:[[1, 2], [3, 4]]

こちらも単純に、変数list_aに変数list_bの要素が追加されました。

2次元リストを乗算

list_a = [[1, 2]]*2

print(list_a)

出力結果:[[1, 2], [1, 2]]

2次元リストのまま変数list_aの要素が繰り返され、要素数が2倍になりました。

2次元リストの検証結果

加算または乗算することで、2次元リストの要素数が2次元リストのまま増えます。

1次元リストと2次元リストの組み合わせの場合を検証

1次元リストと2次元リストを加算

list_a = [[1, 2]]
list_b = [3, 4]

print(list_a + list_b)

出力結果:[[1, 2], 3, 4]

リストは1つにまとまったものの、変数list_aの部分は2次元リスト、list_bの部分は1次元リストという結果になりました。

では、累算代入演算子を使って加算するとどうなるでしょうか。

list_a = [[1, 2]]
list_b = [3, 4]

list_a += list_b

print(list_a)

出力結果:[[1, 2], 3, 4]

元の変数list_aの部分は2次元リストで、追加されたlist_bの部分は1次元リストのままという結果になりました。

1次元リストと2次元リストの組み合わせの場合の検証結果

加算または乗算することで、リストを1つにすることはできますが、2次元リストの部分は2次元リストのまま、1次元リストの部分は1次元リストのまま要素数が増えます。

おわりに

検証結果は、おおよそ想定どおりでした。

ただ、リストの加算または乗算のパターンを知ることで、リストの操作がしやすくなるので、検証する価値はありました。

ほかのデータの集合でも検証すると面白いかもしれませんね!

Pythonのユーザ定義関数を「y=2x+1」を使って解説する

はじめに

以前ブログで「VBAのFunctionプロシージャを「y=2x+1」を使って解説する」という記事を書きました。

lbibouroku.hatenablog.com

今回はそのPython版です。

VBAの記事のときも書いたのですが、以前は「自分で関数を作れる」ということがどういうことなのか、正直よくわかりませんでした。「引数」と「戻り値」のことも、解説を読んでも理解しにくかったです。

そんなときにユーザ定義関数を一次関数で表したら、なんとなくわかりやすくなった気がしたので、Pythonでも書いてみようと思いました。

ちなみに一次関数とは、以下のように定義されています。

 a、bを定数とするときy=ax+b(a≠0)で表される関数

コトバンクより抜粋 https://kotobank.jp/word/%E4%B8%80%E6%AC%A1%E9%96%A2%E6%95%B0-433347

この記事のタイトルの一部の「y=2x+1」は一次関数です。

◆目次◆

用語のおさらい

用語 意味
ユーザ定義関数 ユーザーが独自に定義した関数
引数 関数に渡す値
戻り値 関数から受け取る値

ユーザ定義関数のおさらい

Pythonのユーザ定義関数は以下のように作ります。

def 関数名(引数):
    処理
    return 戻り値

引数に値をいれて関数を呼び出したいときは、以下のようにな呼び出し用のスクリプトを作ります。

関数名(引数の値)

「y=2x+1」をユーザ定義関数で作る

では、さっそく「y=2x+1」をPythonのユーザ定義関数で書いてみます。今回は2種類の書き方を紹介します。

まずは1つ目のユーザ定義関数です。処理の部分に「y=2x+1」を書きます。

def linear_function(x):
    y = 2 * x + 1
    return y

「linear_function(直訳:一次関数)」という関数名のユーザ定義関数を作ります。 行いたい処理は「y = 2 * x + 1」です。答えはyの値なので、変数yを戻り値にします。

呼び出し用のスクリプトは、例えば「x=2」の場合は、以下のように書きます。

linear_function(2)

2つ目のユーザ定義関数です。戻り値に処理を書きます。

def y(x):
    return 2 * x + 1

「y」という関数名のユーザ定義関数を作ります。

「2 * x + 1」の処理結果を戻り値とするので、「2 * x + 1」が戻り値となります。つまり「return 2 * x + 1」と書けばいいのです。

このような簡単な処理であれば、戻り値に、行いたい処理を設定してもいいと思います。

呼び出し用のスクリプトは、例えば「x=2」の場合は、以下のように書きます。

y(2)

さいごに

こうやって並べると、1つ目のユーザー定義関数の方がぱっと見でわかりやすいですね(「y = 2 * x + 1」がそのまま入っているので)。

1つ目の書き方だと、複雑な処理も設定できるので、個人的にはこちらの書き方をする場合が多いです。(もちろん、ケースバイケースですが)

このように一次関数で「引数はx、戻り値はy(または処理結果)」と考えていただくと、少しわかりやすくなるかもしれません。

Excelライブラリを学ぶ

はじめに

しばらくブログを書いていなかったので、リハビリとして、2か月前に受けたVBA中級講座の第4回の「Excelライブラリ」の内容について、(リハビリで選ぶには、ハードな題材だけど・・・)一部まとめを書きます。

◆目次◆

VBAで出てくる用語のおさらい

まずはExcelライブラリと向き合うにあたって、出てくる用語の意味を調べなおします。

用語 意味
ライブラリ モジュールをまとめたもの
クラス クラスモジュールにオブジェクトとそのメンバーを定義したもの
モジュール 宣言ステートメントをまとめたもの
オブジェクト 操作対象のすべてのもの(セル、シート、ブック、グラフなど)
コレクション 同じ種類のオブジェクトをまとめたもの
メンバー コレクションの1つ1つのオブジェクトのこと
グローバル どこからでも同じように参照できるもの
(対義語は「ローカル」、あるいは「プライベート」)

これらをふまえて、Excelライブラリとは何かを確認します。

Excelライブラリとは

Excelライブラリの概要

Excelを操作するためのライブラリです。

Excel VBAでは初期状態で「Microsoft Excel 16.0 Object Library」が参照可能な状態になっています。

f:id:lbibouroku:20211120001229p:plain

Excelライブラリでは、Excelのさまざまなものが、クラスとして定義されています。

f:id:lbibouroku:20211120001242p:plain

このExcelライブラリを使ってVBAで操作することを「Excel VBA」といいます。

VBAではExcelを操作するときに、上位のオブジェクトから配下のオブジェクトをたどって操作対象のオブジェクトを取得します。

Excelライブラリの階層構造はこんな感じです。

Applecation
    |
    |- WorkSheets
        |
        |- Sheets
            |
            |- Range

Excelライブラリの参照

Excelライブラリはすべてクラスで構成されています。言い換えると、Excelライブラリはすべてオブジェクトモジュールでできています。

Excelライブラリには、取得するオブジェクト型と同名のプロパティ名が存在します。配下のオブジェクトを取得するには、以下のようにコードを書きます。

オブジェクト.プロパティ

でも、VBAで以下のようにコードを書いてもエラーにはならないですよね(上位オブジェクトが省略できます)。

Sub test1()
    Debug.Print Range("A1")
End Sub

本来であれば、Rangeオブジェクトを操作するには、Applecationクラスからたどるように、コードを書かないといけないはずです。

なぜエラーにならないのでしょうか。

それは、VBAでは「グローバルのメンバーは上位オブジェクトを省略できる」というルールがあるからです。

(すべてのメンバーを表示しきれていませんが)以下の赤枠内「<グローバル>のメンバー」は、上位オブジェクトを省略できます。

f:id:lbibouroku:20211120001257p:plain

以下のとおり、RangeはExcelライブラリのグローバルのメンバーです。

f:id:lbibouroku:20211120001313p:plain

上位オブジェクトを省略できたのは、こういう背景があったのですね。

上位オブジェクト省略時の注意事項

さて、Excelライブラリのグローバルのメンバーであれば、上位オブジェクトを省略できることはわかりました。

しかし、むやみに省略すると問題が発生する場合あります。大きな理由は以下の2点です。

  • モジュールによって省略の意味が変わるから(シートモジュールと標準モジュールでは結果が異なる場合がある)
  • ユーザー操作の干渉を受けるから(ユーザーが選択しているオブジェクトによって結果が異なる場合がある)

さいごに

Excelライブラリについて、講座の内容をひとつずつかみ砕きながら解き進めました。今回の肝はここでした。

それは、VBAでは「グローバルのメンバーは上位オブジェクトを省略できる」というルールがあるからです。

実は、講座では続きがあって、「既定のメンバー」について解説を受けました。

が、長くなるので、それはまた別の機会に書きます(そのときは_Defaultプロパティについて書くのか、大変だなあ・・・)。

VBAツール ※この記事は個人的な備忘録です

はじめに

  • この記事は個人的な備忘録です。
  • 業務で使用するためのサンプルツール用のコードなどを記述します。書きかけのコードもあります。
  • あくまでサンプルのため、コードの実践は自己責任でお願いします。

概要

転記ツール

'[Module1]
Enum header
    旧型番 = 1
    旧製品名
    旧受注停止日
    旧出荷停止日
    新型番
    新製品名
    新受注停止日
    新出荷停止日
    製品名
    掲載順判定
End Enum

Sub 掲載用販売停止情報作成()

    Call 新型番表シート.最終行確認
    Call 旧型番表シート.配列作成
    Call 掲載順シート.最終行確認
    Call 掲載用_販売停止情報シート.最終行確認
    
    Call 対象外型番判定

    Call 販売停止情報転記
    Call 掲載順整理
    
    Call 掲載用_販売停止情報シート.セル結合
    Call 掲載用_販売停止情報シート.製品名挿入

End Sub

Function 旧製品名検索一致(ByVal i As Long) As String

    Dim j As Long
    For j = 2 To UBound(旧型番表シート.配列, 1)
        If 新型番表シート.Cells(i, 11).Value = 旧型番表シート.配列(j, 1) Then
            旧製品名検索一致 = 旧型番表シート.配列(j, 3)
        End If
    Next j

End Function


Function 掲載順置換(ByVal i As Long) As String

    Dim order As String
    Dim j As Long
    For j = 2 To 掲載順シート.最終行_製品名
        
        If Left(新型番表シート.Cells(i, 11).Value, 6) = 掲載順シート.Cells(j, 1).Value Then
            order = 掲載順シート.Cells(j, 3).Value
        End If
    Next j
    
    order = order & "_" & 新型番表シート.Cells(i, 9).Value
    
    For j = 2 To 掲載順シート.最終行_分類
        If 新型番表シート.Cells(i, 2).Value = 掲載順シート.Cells(j, 4).Value Then
            order = order & "_" & 掲載順シート.Cells(j, 5).Value
        End If
    Next j

    掲載順置換 = order

End Function

Sub 対象外型番判定()

    Dim i As Long
    For i = 2 To 新型番表シート.最終行
        If Mid(新型番表シート.Cells(i, 1).Value, 4, 1) = "P" Then
            MsgBox 新型番表シート.Cells(i, 1).Value & "はPシリーズ製品です。処理を中止するので" & i & "行目を削除してください。"
            Exit Sub
        ElseIf 新型番表シート.Cells(i, 11) = "-" Then
            MsgBox 新型番表シート.Cells(i, 1).Value & "は前バージョンがない製品です。処理を中止するので" & i & "行目を削除してください。"
            Exit Sub
        End If
    Next i

End Sub

Sub 販売停止情報転記()


    Dim num As Long  '販売停止情報シートのカウンタ関数
    num = 1
    
    Dim i As Long
    For i = 2 To 新型番表シート.最終行
        num = num + 1
        With 販売停止情報シート
            .Cells(num, header.旧型番).Value = 新型番表シート.Cells(i, 11).Value
            .Cells(num, header.旧製品名).Value = 旧製品名検索一致(i)
            .Cells(num, header.旧受注停止日).Value = 旧製品受注出荷停止日シート.Cells(2, 1).Value
            .Cells(num, header.旧出荷停止日).Value = 旧製品受注出荷停止日シート.Cells(2, 2).Value
            .Cells(num, header.新型番).Value = 新型番表シート.Cells(i, 1).Value
            .Cells(num, header.新製品名).Value = 新型番表シート.Cells(i, 3).Value
            .Cells(num, header.新受注停止日).Value = 新型番表シート.Cells(i, 7).Value
            .Cells(num, header.新出荷停止日).Value = 新型番表シート.Cells(i, 8).Value
            .Cells(num, header.製品名).Value = 製品名抽出(i)
            .Cells(num, header.掲載順判定).Value = 掲載順置換(i)
        End With
    Next i

End Sub

Function 製品名抽出(ByVal i As Long) As String

    Dim j As Long
    For j = 2 To 掲載順シート.最終行_製品名
        If Left(新型番表シート.Cells(i, 11).Value, 6) = 掲載順シート.Cells(j, 1).Value Then
               製品名抽出 = 掲載順シート.Cells(j, 2).Value
        End If
    Next j

End Function

Sub 掲載順整理()

    Dim 転記範囲 As Range
    Set 転記範囲 = 販売停止情報シート.Range("A1").CurrentRegion
    
    With 転記範囲
        .Sort Key1:=.Range("J1"), Order1:=xlAscending, header:=xlYes
        .Resize(.Rows.Count - 1).Offset(1, 0).Copy
    End With
    
    掲載用_販売停止情報シート.Range("B9").PasteSpecial Paste:=xlPasteValues
    
End Sub
[旧型番表シート]
Public 配列 As Variant

Sub 配列作成()
  配列 = Cells(1, 1).CurrentRegion.Value
End Sub
[掲載順シート]
Public 最終行_製品名 As Variant
Public 最終行_分類 As Variant

Sub 最終行確認()    
    最終行_製品名 = Cells(Rows.Count, 1).End(xlUp).Row
    最終行_分類 = Cells(Rows.Count, 4).End(xlUp).Row
End Sub
[掲載用_販売停止情報シート]
Public 最終行 As Long

Sub 最終行確認()
  最終行 = Cells(Rows.Count, 2).End(xlUp).Row
End Sub

Sub セル結合()
    Call 最終行確認
    
    Application.DisplayAlerts = False
    Dim i As Long
    For i = 9 To 最終行 Step 3
        Range(Cells(i, 3), Cells(i + 2, 3)).Merge
        Range(Cells(i, 7), Cells(i + 2, 7)).Merge
    Next i
    Application.DisplayAlerts = True
    Range("C:C").WrapText = True
    Range("G:G").WrapText = True

End Sub

Sub 製品名挿入()
    Call 最終行確認
    Dim i As Long
    For i = 最終行 To 9 Step -1
        If Cells(i, 10) <> Cells(i - 1, 10) And Cells(i - 1, 10) <> "" Then
            Rows(8).Copy
            Rows(i).Insert Shift:=xlDown
            Application.CutCopyMode = False
            Cells(i, 2).Value = Cells(i + 1, 10).Value
        ElseIf Cells(i - 1, 10) = "" Then
            Cells(i - 1, 2).Value = Cells(i, 10).Value
        End If
    Next i
    
    Range("J:K").Delete
    Rows(最終行 & ":1000").Delete
End Sub
[新型番表シート]
Public 最終行 As Long

Sub 最終行確認()
  最終行 = Cells(Rows.Count, 1).End(xlUp).Row
End Sub

シート名など

f:id:lbibouroku:20211028081732p:plain f:id:lbibouroku:20211028081754p:plain f:id:lbibouroku:20211028081817p:plain f:id:lbibouroku:20211028081840p:plain