
うん~~ まだ取り合えずつくってみましたか程度だな。日付にカレンダーフォームを使いたいし、エラーチェックなど入れたいな。まだまだこれからだなという顔をしている柴犬です。
概要
前回の投稿から、アフィリエイトの広告文を載せています。
ちょっと前から広告文をどのようにするか考えていましたが、書式などレイアウトを決めました。
ワードプレスに広告文を挿入する手間をなるべく簡単にしたいので、
1.フォームに画像のURL、文のURLをテキストボックスにコピー貼り付けする。
2.タイトル、詳細、現在日、ブラウザのボタンの表題はテキストボックスに入力する。
3.これらのデータからフォームのボタン「クリップボード」をクリックするとワードプレスに貼り付ける文書がクリップボードに作られる。
4.このクリップボードの文書をワードプレスのコードエディターで開いて希望のところに貼り付ける。
このようにすればかなりの長文の URL文でも取り扱いを省力化できます。
Delphi5 があるのでそれで作ろうかなと思いましたが、もう25年前のことで忘れていることも多いし、パスカルなので、 やはり手軽なのはEXCELです。
それで、EXCELでやってみたことを記事にしてみました。
作成できるのはこんな具合の広告文です。
フォーム
フォームのレイアウトは次のようになっています。
テキストボックスのオブジェクト名は、テキストボックスの文字としています。

プロパティ
プロパティは次のようにしています。MultiLine を True にします。

使用方法
各店舗の画像・テキストのURLをコピーして貼り付けます。
タイトル・詳細・店舗1~3のボタン表題、作成日を編集します。
フォームのボタン「クリップボード」をクリックして貼り付け文章をクリップボードにコピーします。

ワードプレスの貼り付け
ワードプレスのエディターをビジュアルコードエディターからコードエディターに変更します。
変更は、ワードプレス画面の右上の・が縦に3個並んだアイコンをクリックすると、メニューが表示されますので、コードエディターをクリックするだけです。

貼り付けたい位置(この場合四角の青色の位置)のにプロンプトを持っていきマウスの右クリック「貼り付け」またはキー 「Ctrl」 + 「V」 押下でクリップボードから貼り付けます。
これだけで終わりで、下の画面は貼り付け後です。

フォームのコード
メイン
*****動作せずのところは、他のホームページでも紹介されていますが、クリップボードにコピーされませんでした。
したがって、API関数で処理することにしました。
Option Explicit
Private myText As String
'
'-----------------------------------------------------------------
Private Sub クリップボード_Click()
myText = ""
Call makemyText
Call setPicturURL
Call setTopURL
Call setRakutenURL
Call setAmazonURL
If myText <> "" Then
myText = Replace(myText, "#DetailText#", Me.DetailText.Value)
myText = Replace(myText, "#MakeDate#", Me.MakeDate.value)
Call SetClipboard(myText)
'*****動作せず
'With New DataObject
' .SetText myText
' .PutInClipboard
'End With
Else
MsgBox "データを作成できませんでした。"
End If
End Sub
'
'-----------------------------------------------------------------
Private Sub 閉じる_Click()
Unload Me
End Sub
画像URLの処理
'
'-----------------------------------------------------------------
Private Sub setPicturURL()
Dim buf As String
buf = Me.PictureURL.Value
If InStr(buf, "<a href") > 0 And _
InStr(buf, "</a>") > 0 And _
InStr(buf, "<img") > 0 Then
myText = Replace(myText, "#PictureURL#", buf)
Else
myText = ""
End If
End Sub
見出し・第一店舗部分の処理
'
'-----------------------------------------------------------------
Private Sub setTopURL()
Call changeURL("#TopURL#", Me.TopURL.Value, Me.TopCaption.Value)
End Sub
'
'-----------------------------------------------------------------
Private Sub setRakutenURL()
Call changeURL("#RakutenURL#", Me.RakutenURL.Value, Me.RakutenCaption.Value)
End Sub
'
'-----------------------------------------------------------------
Private Sub changeURL(inv As String, url As String, cap As String)
Dim res As String
Dim s As String
If InStr(url, "<a href=") = 1 And Right(url, 4) = "</a>" Then
s = InStr(url, ">")
If s = InStrRev(url, ">", Len(url) - 1) Then
res = Left(url, s) & cap & "</a>"
res = Replace(res, "<a ", "<a style=""word-wrap: break-word;"" ")
End If
End If
If res <> "" Then
myText = Replace(myText, inv, res)
Else
myText = ""
End If
End Sub
第二・第三店舗部分の処理
'
'-----------------------------------------------------------------
Private Sub setAmazonURL()
Call changeAmazonURL("#AmazonURL#", Me.AmazonURL.Value)
Call changeAmazonURL("#AmazonCaption#", Me.AmazonCaption.Value)
Call changeAmazonURL("#KindleURL#", Me.KindleURL.Value)
Call changeAmazonURL("#KindleCaption#", Me.KindleCaption.Value)
End Sub
'
'-----------------------------------------------------------------
Private Sub changeAmazonURL(inv As String, urlcap As String)
Dim res As String
If InStr(inv, "URL") > 0 Then
If InStr(urlcap, "<a href=") = 0 And _
InStr(urlcap, "</a>") = 0 Then
res = urlcap
End If
Else
res = urlcap
End If
If res <> "" Then
myText = Replace(myText, inv, urlcap)
Else
myText = ""
End If
End Sub
加工する基本文
ワードプレスに挿入するHTML文も置き換える文の一塊を一文に置き換えると簡潔な文になります。
#PictureURL# #TopURL# #DetailText# #MakeDate# #RakutenURL# #AmazonURL# #AmazonCaption# #KindleURL# #KindleCaption# という具合に#で囲んでこれを単位としてHTML文の中での位置決めをしてます。
この単位文を目的の URL文、ブラウザのボタンの表題、タイトル、作成日などを入れ替える作業をします。
class名は黒塗りにしました。
'
'-----------------------------------------------------------------
Private Sub makemyText()
myText = myText & "<div class=""■■■■■"">" & Chr(10)
myText = myText & "<div class=""■■■■■"">" & Chr(10)
myText = myText & "<div class=""■■■■■"">" & Chr(10)
myText = myText & "#PictureURL#" & Chr(10)
myText = myText & "</div>" & Chr(10)
myText = myText & "<div class=""■■■■■"">" & Chr(10)
myText = myText & "<div class=""■■■■■"">" & Chr(10)
myText = myText & "#TopURL#" & Chr(10)
myText = myText & "</div>" & Chr(10)
myText = myText & "<div class=""■■■■■"">#DetailText#</div>" & Chr(10)
myText = myText & "<p class=""■■■■■"">#MakeDate#</p>" & Chr(10)
myText = myText & "<div class=""■■■■■"">" & Chr(10)
myText = myText & "<div class=""■■■■■"">" & Chr(10)
myText = myText & "#RakutenURL#" & Chr(10)
myText = myText & "</div>"
myText = myText & "<div class=""■■■■■"">" & Chr(10)
myText = myText & "<a href=""#AmazonURL#"">#AmazonCaption#</a>" & Chr(10)
myText = myText & "</div>" & Chr(10)
myText = myText & "<div class=""■■■■■"">" & Chr(10)
myText = myText & "<a href=""#KindleURL#"">#KindleCaption#</a>" & Chr(10)
myText = myText & "</div>" & Chr(10)
myText = myText & "</div>" & Chr(10)
myText = myText & "</div>" & Chr(10)
myText = myText & "</div>" & Chr(10)
myText = myText & "</div>"
End Sub
URL文を貼り付けたときの処理
テキストボックス「TopUR」「RakutenURL」にURL文を貼り付けたときテキストボックス「TopCaption」「RakutenCaption」にブラウザの表示部分を反映させます。
'
'-----------------------------------------------------------------
Private Sub TopURL_Change()
Call setCaption(Me.TopURL.Text, "TopCaption")
End Sub
'
'-----------------------------------------------------------------
Private Sub RakutenURL_Change()
Call setCaption(Me.RakutenURL.Text, "RakutenCaption")
End Sub
'
'-----------------------------------------------------------------
Private Sub setCaption(inputStr As String, setCtrl As String)
Dim s As String
Dim res As String
If InStr(inputStr, "<a href=") > 0 And _
InStr(inputStr, "</a>") > 0 Then
s = InStr(inputStr, ">")
If s = InStrRev(inputStr, ">", Len(inputStr) - 1) Then
res = Mid(inputStr, s + 1)
res = Left(res, InStr(res, "<") - 1)
End If
End If
Me(setCtrl).Value = res
End Sub
標準モジュールのコード
Microsoft の次のホームページの「クリップボードに情報を送信する Windows API を使用する」からのコードを使います。
https://learn.microsoft.com/ja-jp/office/vba/access/concepts/windows-api/send-information-to-the-clipboard
そのままのコードでは 64bit Windows では動作しませんので次のように修正しました。その修正は、hMem は Long型ではだめでLongPtr型にして、それに合わせて他も Long型から LongPtr型にすることです。
Option Explicit
'
'-----------------------------------------------------------------
#If VBA7 And Win64 Then
Private Declare PtrSafe Function OpenClipboard _
Lib "user32.dll" (ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function EmptyClipboard _
Lib "user32.dll" () As Long
Private Declare PtrSafe Function CloseClipboard _
Lib "user32.dll" () As Long
Private Declare PtrSafe Function IsClipboardFormatAvailable _
Lib "user32.dll" (ByVal wFormat As Long) As Long
Private Declare PtrSafe Function GetClipboardData _
Lib "user32.dll" (ByVal wFormat As Long) As Long
Private Declare PtrSafe Function SetClipboardData _
Lib "user32.dll" (ByVal wFormat As Long, _
ByVal hMem As LongPtr) As Long
Private Declare PtrSafe Function GlobalAlloc _
Lib "kernel32.dll" (ByVal wFlags As Long, _
ByVal dwBytes As Long) As LongPtr
Private Declare PtrSafe Function GlobalLock _
Lib "kernel32.dll" (ByVal hMem As LongPtr) As LongPtr
Private Declare PtrSafe Function GlobalUnlock _
Lib "kernel32.dll" (ByVal hMem As LongPtr) As Long
Private Declare PtrSafe Function GlobalSize _
Lib "kernel32" (ByVal hMem As LongPtr) As Long
Private Declare PtrSafe Function lstrcpy _
Lib "kernel32.dll" Alias "lstrcpyW" (ByVal lpString1 As LongPtr, _
ByVal lpString2 As LongPtr) As Long
#Else
Private Declare Function OpenClipboard _
Lib "user32.dll" (ByVal hWnd As Long) As Long
Private Declare Function EmptyClipboard _
Lib "user32.dll" () As Long
Private Declare Function CloseClipboard _
Lib "user32.dll" () As Long
Private Declare Function IsClipboardFormatAvailable _
Lib "user32.dll" (ByVal wFormat As Long) As Long
Private Declare Function GetClipboardData Lib _
"user32.dll" (ByVal wFormat As Long) As Long
Private Declare Function SetClipboardData Lib _
"user32.dll" (ByVal wFormat As Long, _
ByVal hMem As Long) As Long
Private Declare Function GlobalAlloc Lib _
"kernel32.dll" (ByVal wFlags As Long, _
ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock _
Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock _
Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalSize _
Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function lstrcpy _
Lib "kernel32.dll" Alias "lstrcpyW" (ByVal lpString1 As Long, _
ByVal lpString2 As Long) As Long
#End If
'
'-----------------------------------------------------------------
Const GMEM_MOVEABLE As Long = &H2
Const GMEM_ZEROINIT As Long = &H40
Const CF_UNICODETEXT As Long = &HD
'
'-----------------------------------------------------------------
Public Sub SetClipboard(sUniText As String)
Dim iStrPtr As LongPtr
Dim iLen As Long
Dim iLock As LongPtr
Dim res As Long
res = OpenClipboard(0&)
res = EmptyClipboard
iLen = LenB(sUniText) + 2&
iStrPtr = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, iLen)
iLock = GlobalLock(iStrPtr)
res = lstrcpy(iLock, StrPtr(sUniText))
res = GlobalUnlock(iStrPtr)
res = SetClipboardData(CF_UNICODETEXT, iStrPtr)
res = CloseClipboard
End Sub
'なぜか iLock iLen が取得できない。原因不明。
'取得できるようになれば、この GetClipboard を使ってもっと省力化できる。
'-----------------------------------------------------------------
Public Function GetClipboard() As String
Dim iStrPtr As LongPtr
Dim iLen As Long
Dim iLock As LongPtr
Dim sUniText As String
Dim res As Long
Const CF_UNICODETEXT As Long = 13&
res = OpenClipboard(0&)
If IsClipboardFormatAvailable(CF_UNICODETEXT) Then
iStrPtr = GetClipboardData(CF_UNICODETEXT)
If iStrPtr Then
'なぜか 0
iLock = GlobalLock(iStrPtr)
'なぜか 0
iLen = GlobalSize(iStrPtr)
'iLen が 0 だと致命的エラー 再起動が必要
If iLen > 1 Then
sUniText = String$(iLen \ 2& - 1&, vbNullChar)
Else
sUniText = String$(0, vbNullChar)
End If
res = lstrcpy(StrPtr(sUniText), iLock)
res = GlobalUnlock(iStrPtr)
End If
GetClipboard = sUniText
End If
res = CloseClipboard
End Function
関数「SetClipboard」「GetClipboard」の中で、原文にはない変数 res で値を受け取っています。
それぞれのAPI関数は実行でエラーになると 0 を返しますので、変数 res の値は 0 になります。
原文のままではエラーになりましたので、変数 res で受けてどこで変数res が 0 になるのか確認し、Long型 を LongPtr型 しました。
本来は値をチェックしながら実行するようにするのでしょうが今回はそこまでする必要がないので、初めに確認できれば削除して原文のようにしてもいいのでしょう。