Fippiyのプログラム学習内容アウトプットBlog

日々の学習内容をアウトプットして振り返りを実施する。

VBAプログラム開発、スクレイピング・一覧取得【4-1】オブジェクト名を設定する

書籍一覧情報をワークシートへ取得していました。

今回はこのワークシートに取得済みのデータについて、Web側の情報取り込み時にWeb側で削除されている書籍についてワークシート側でも削除できるようにしていきます。

そして、その前段階として画像オブジェクト処理に手を加えます。

今回の目的

特定のオブジェクトを操作できるように、固有名を付与する

なぜやるか

不要書籍削除時に、対象となる書籍の画像を指定できるようにするため

やりたいこと

  • オブジェクト名を取得する
  • オブジェクトに固有の名前を付ける

やったこと

  • オブジェクト操作方法を検討する
  • オブジェクト名を取得できるようにする
  • オブジェクト追加時にオブジェクト名を設定する

実施内容

書籍情報削除をできるようにする

行削除だけでは全て消えない

ワークシート上の書籍情報削除にあたり、画像データの扱いをどうするか検討していました。

オートシェイプとして、書籍画像を反映させていたのですが、データ削除として行ごと削除を行うと、テキストデータが消去されて続くデータが上詰めとなるので、見た目は消えています。

しかし、オートシェイプとして貼り付けた画像は、このままでは削除対象とならず、どんどんデータが残っていきます。

ワークシート上で2行目以降を選択して行ごと削除すると…。

f:id:Fippiy:20190709132416j:plain

データ削除前

テキストは削除されるが、オブジェクトは残存する。

f:id:Fippiy:20190709132522j:plain

データ削除後
画像の削除も行えるようにしたい  

追加時は追加したい画像に対して、位置指定すれば処理が完了していました。

では、削除はどうするか?

ここで、オブジェクト操作について調べてみました。

こちらを参考にさせて頂きました、ありがとうございます。

www.moug.net

オブジェクトに対しての名前を取得する方法です。

名前が取得できれば、指定した要素に対してのコントロールも行えると考え、こちらを元にオブジェクト操作を行えるようにしようと考えました。

そこで、まずは削除処理の前にオブジェクト名の取得から、特定の書籍の画像であることが分かる名前を付けることにしました。

書籍画像オブジェクト名を設定する

オブジェクト名を取得する

まずは、先程の参考サイトを元にワークシート上の書籍画像オブジェクトの名前を取得します。 

# テスト用プロシージャ(オブジェクト名取得)

Sub testobjname()
 Dim strObjName() As String
 Dim intObj As Integer
 Dim i As Integer

 'アクティブシートのShapes数をカウント
 intObj = ActiveSheet.Shapes.Count
 '配列を再宣言
 ReDim strObjName(intObj)

 '配列strObjNameにオブジェクト名を代入
 For i = 1 To intObj
  strObjName(i) = ActiveSheet.Shapes(i).Name
 Next i

 '配列strObjNameに代入されたオブジェクト名を表示
 For i = 1 To intObj
  Debug.Print strObjName(i)
 Next i
End Sub

動作確認して、オブジェクト名が取得できていることを確認します。

f:id:Fippiy:20190709110402j:plain

オブジェクト名

名前が取得できました。

ワークシート上のオブジェクト情報と照らし合わせてみます。

f:id:Fippiy:20190709110459j:plain

Excel上のオブジェクト表示

同じ名前になっていました。

これで、VBAコードでオブジェクト名は取得できています。

 

書籍情報に対応したオブジェクト名をつける 

書籍画像は書籍情報を取得しワークシートへ反映させるときにテキストデータと共に反映されていました。

この反映処理時にID名を付与できるようにします。

名前の付与についてはこちらを参考にさせて頂きました、ありがとうございます。

 

エクセルのマクロで図形を操作する(3) – オートシェイプに名前をつけるmatsumotoyoshio.wordpress.com

対象となるオートシェイプを指定して名前を変更する…それだけです。

# 参考サイト記述

ActiveSheet.Shapes(1).Name = “taro”

.Shapes(x)としてオブジェクトを選択して、nameプロパティで文字を指定すれば名前が変更されます。

 

これをどうにかして新規書籍追加時の画像に対して追加処理としていれてやれば良さそうです。 

 

画像追加時のオプションにオートシェイプ名付与がない

画像追加処理を再度確認します。

# 書籍詳細情報取得(オブジェクト追加)

SWSheet.Shapes.AddPicture _
 fileName:=ImgURL.src, _
  LinkToFile:=False, _
  SaveWithDocument:=True, _
  Left:=ActCell.Left, _
  Top:=ActCell.Top, _
  Width:=100, _
  Height:=100

画像ファイルの選択や貼り付け位置といったオプションはありますが、オブジェクト名の指定はありません。

この段階で指定ができないので、画像オブジェクト追加後に名前を変更する必要があります。

 

オブジェクト要素をどうやって指定するか

# 参考サイト記述

ActiveSheet.Shapes(1).Name = “taro”

しかし、ここで追加された画像をどうやって指定するかとい問題があります。

要素指定は番号となっており、ワークシート上に存在するオブジェクト毎い番号が振られています。

これは、オブジェクト名取得時もそうでした、設置されているオブジェクト数を取得して、番号を繰り返すことで結果的に全オブジェクトの名前を取得していました。

新規追加オブジェクトの順序が分かれば良い

オブジェクト名取得時に全要素の数を調べて、全出力していた…ということはその後に追加されたオブジェクトは全数+1となります。

新しいオブジェクトが増えると言うことは、順序としては全数+1の値を利用すれば、この段階で新規追加オブジェクトが指定できそうです。

ここで、書籍画像としてのID名を付与しておけば、後から削除の際にはオブジェクトの番号が分からなくても、名前としてID名が付与されているので、これで直接オブジェクトを指定できそうです。

 

オブジェクト数を算出してから追加オブジェクトを処理する 

そこで、書籍情報取得VBAに対してオートシェイプ総数を確認と、画像追加後のオートシェイプ名設定を加えてみました。

# 書籍詳細情報取得(新規レコード追加処理・抜粋)

Sub getDetailBookdata(SWSheet As Worksheet, objIE As InternetExplorer, _

  URLCol As Collection, Login As BookdataLogin, i As Long)

 'オブジェクト設定

  ~ 省略 ~

  'オブジェクト処理
  Dim objCount As Long
  'アクティブシートのShapes数をカウント
  objCount = SWSheet.Shapes.Count

 '詳細ページURLを展開してデータ取得
 Do

  ~ 省略 ~

  '2列目に画像表示
  Set DocPicture = Login.htmlDoc.getElementsByClassName("book-detail__picture")(0)
  Set ImgURL = DocPicture.getElementsByTagName("img")(0)
  Set ActCell = SWSheet.Cells(i, j)
  SWSheet.Shapes.AddPicture _
   fileName:=ImgURL.src, _
    LinkToFile:=False, _
    SaveWithDocument:=True, _
    Left:=ActCell.Left, _
    Top:=ActCell.Top, _
    Width:=100, _
    Height:=100
  '増えたオブジェクトに名前付与
  objCount = objCount + 1 '取得済みオートシェイプの次を指定
  ActiveSheet.Shapes(objCount).Name = GetID 'ID名を付与
  j = j + 1
  '3列目以降にテキスト表示
  For Each DocContent In Login.htmlDoc.getElementsByClassName("document-content")
  Set DocColumn = DocContent.getElementsByClassName("document-content__column")(0)
  SWSheet.Cells(i, j).Value = DocColumn.innerHTML
  j = j + 1
 Next DocContent

  ~ 省略 ~

End Sub

追加する書籍のURLが決定した後の、実際に書籍情報をワークシートへ出力するプロシージャとなっていました。

まず、データが追加される前にオートシェイプの総数を取得しておきます。

そして、新しい書籍画像追加後に総数+1として新規追加画像を指定しました。そこに、オートシェイプ名=ID名を付与しています。

 

データを再取得してオブジェクト名を確認する

この状態で、ワークシート上の書籍情報を1件削除から再取得してみました。

f:id:Fippiy:20190709114745j:plain

ID名付与オートシェイプ

ID347の書籍をVBAにより再取得しました。

右側のオブジェクト一覧の一番上にも同じく347の名前があり、名前付与ができています。

 

これで動作はできていそうですが、全データで再確認します。

f:id:Fippiy:20190709115546j:plain

オートシェイプ名変更

ワークシートに全書籍データを取得しなおしました。

オブジェクト名にID名が付与されて出力されました。

 

以上で、書籍画像に対してID名を付与したオブジェクトにすることができました。

これを利用して、ワークシート上の書籍削除を実装していきます。