MAX7219の使い方 8×8LCD 無ライブラリー (3)

あれこれやっていましたが,やっとまた1つ理解が進みました。これも,分かってる方からすればな
んでもないことなのでしょうが,改めて理解できたというところです。
単体(1つだけ)の書き込みをしてる分にはいいのですが,for等で繰り返し処理をすると2回目以降
の書き込みで,1番目にLED書き込んたデータが2番目,3番目,4番目と順次表示されます。書き込
みは1番目のLEDなのに2番目以降のLEDに表示されるが理解できませんでした。これもやっと理解でき
ました。

 一度書き込まれたデータの後に書き込みを行うと,
 先に書き込まれたデータに上書きされるのではなく,
 先に書き込まれたデータは,次以降のLEDに順送りにされる。

このことが分からなくて,思った動作をさせられず,もがきました。

 for(int i=1;i<9;i++){
    maxTransfer(i,1);
    digitalWrite(CS_PIN, HIGH);
    delay(500);
  }

この繰り返しのスケッチは,一番左に1つドットを描き,それを一番下まで繰り返すスケッチです。このまま
だと動画のようになります。

それと, digitalWrite(CS_PIN, HIGH); の命令は,本来 maxTransfer( ,); のサブ関数内で一括処理して
た、ものです,データをかきこんだらそれをレジスタにその都度アップロード・ラッチを行う処理でした。
データの書き込み--アップロード(ラッチ)と一連の流れで処理してしまうと,別な命令の書き込み
ができないので,諸兄スケッチから変更しました。こうすることで、下記のスケッチのように、何もしない
命令( maxTransfer(0,0))を2番目、3番目、4番目のLEDに先送りにし、一度にデータをアップロード
ラッチすることで、余分な表示を防げます。

for(int i=1;i<9;i++){
    maxTransfer(0,0);
    maxTransfer(0,0);
    maxTransfer(0,0);
    maxTransfer(i,1);
    digitalWrite(CS_PIN, HIGH);
    delay(500);
  }

2番目,3番目,4番目に先に送られたno-opコードのため余分な表示がされなくなります。

一度表示されると,消去するまで,表示されますので,次のように一度表示したものを消去すると移動するよ
うに見えます。

For(int i=1;i<9;i++){
    maxTransfer(0,0);
    maxTransfer(0,0);
    maxTransfer(0,0);
    maxTransfer(i,1);
    digitalWrite(CS_PIN, HIGH);
    delay(500);
    maxTransfer(0,0);
    maxTransfer(0,0);
    maxTransfer(0,0);
    maxTransfer(i,0);
    digitalWrite(CS_PIN, HIGH);
  }

ここまでたどり着くのに結構時間がかかりました。ライブラリーを作成している先達は,いち早くこういうこ
とが理解できたのでしょうね。凡人はとてつもなく時間がかかります。

MAX7219の使い方 8×8LCD 無ライブラリー (2)

あれこれやってますが,どのHPを見ても,二個目,三個目,四個目のMAX7219に指令を出す方々が書いてあ
りませんでした。これまでかと思い,取説を確認してみるとありました。ありました。きちんと表記があるじゃないですか。

  ===二つ目以降のチップを操作する===

 4つのMAX7219をカスケード接続する場合,4番目のチップに書き込みを行うには,希望する
 16ビットワードの後に,3つのno-noコード(16進の0xXX0X表2)送信します。
 LOAD/CSがハイになった時点で,すべてのデバイスにデータがラッチられます。最初の3つのチップ
 は,no-noコマンドを受け取り,4番目のチップが目的のデータを受け取ります。

とありました。これで,もうちょっと先に進めそうです。

また,諸兄のHPを参考にarduino風に書き換えていた,SPIのデータ書き込みのスケッチも動きました。

#define CLK 13
#define DIN 11
#define CS  10

void setup(){
  Serial.begin( 9600 );     // シリアル通信を初期化する。通信速度は9600bps
    pinMode(CLK, OUTPUT );
    pinMode(DIN, OUTPUT );
    pinMode(CS, OUTPUT );
}

void wait(int i){
  volatile int j,k;
  for(j=0;j<i;j++){
    for(k=0;k<55;k++);
  }
}

//****************************************************************
//arduino自作関数
//データ書き込み
//****************************************************************
void LED_MAT_SEND(unsigned char SELECT, unsigned char DATA){
  digitalWrite( CS, HIGH );// Load ON
  wait(2);void 
  digitalWrite( CS, LOW );// Load OF

  for(int i=0;i<8;i++){               // Send Register data
        digitalWrite( CLK, LOW );//CLK OFF
        if(((SELECT << i) & 0b10000000)==0){
          digitalWrite( DIN, LOW );
          Serial.print( '-' );
        }
        else{
          digitalWrite( DIN, HIGH );
          Serial.print( '+' );
        }
      wait(1);
      digitalWrite( CLK, HIGH );//CLK ON
      wait(1);
  }

  for(int i=0;i<8;i++){               // Send LED DATA
      digitalWrite( CLK, LOW );//CLK OFF


      if(((DATA << i) & 0b10000000)==0){
        digitalWrite( DIN, LOW );
        Serial.print( '-' );
      }
      else{
        digitalWrite( DIN, HIGH );
        Serial.print( '+' );
      }
      wait(1);
      digitalWrite( CLK, HIGH );//CLK ON
      wait(1);
    }
    digitalWrite( CS, HIGH );// Load ON
    wait(2);
    digitalWrite( CS, LOW );// Load OFF
    Serial.print( "******" );
}

デバッグ用のSerial.printは残してあります。また,この, digitalWrite( CLK, HIGH );は結構クロックをつかうようなので,一括処理のものに後で変更しようと思います。このスケッチもSPIライブラリーを使うと,別な諸兄の書かれた下記のように6行程度ですんでしまいます。

void maxTransferCMD(uint8_t address, uint8_t value) {
  digitalWrite(CS_PIN, LOW);
  SPI.transfer(address); // Send address.
  SPI.transfer(value); // Send the value.
  digitalWrite(CS_PIN, HIGH); // Finish transfer.
}

今日,取説で見つけた記述をもとに,2個目3個目のMAX7219に書き込めるスケッチも考えてみたいと思います。

MAX7219の使い方 8×8LCD 無ライブラリー (1)

何年か前に、8×8の小さ目のLCDマトリックスで、PICを使って流れるサインボードのおもちゃを作成しまし
た。ネットサーフィンをしていると、ちょっと大きめの8×8LCDマトリックスがめにとまりましたので、
思わず、いくつかポチってしまいました。

この一つのものと、4連のもの合計3つをアリでぽちりました。

4連のものは、赤と青を購入しました。

この、LCDは、MAX7219というコントロールIC(ドライバー)が使われていて、比較的たやすく、コント
ロールができるようで、arduinoだと、専用のライプラリーもいくつかあるようです。また、このLCDの
面白いのは、横に連結して使えることです。どのくらい連結できるのかわかりませんが、arduinoの設定
の項目には11個の記載がありましたので、もしかして、電源のこと考えないなら、11個ぐらい連結で
きるのかもしれません。

ライブラリーを使えばいいのでしょうが、MAX7219を直接コントロールしたくて、あれこれしらべました。
幸い詳しく書かれている諸兄のHPが見つかりましたので、ここを参考にいろいろやってみます。

いままで、いろんなもののコントロールに、SPI(シリアル通信)を使う記事も見かけましたが、実際は
どんなふうにするのかいまいち理解がおよびませんでしたが、なんとなく理解することができました。
諸兄のHPによれば、下記のようになるそうです。SPIは3本の線でやり取りします。CLK,Cs,DOUTの3本の
線で下記のようにやり取りをします。

 ・Load端子をLowにセット

  -・CLK端子をLowにセット
  +・15ビット目の値をDINにセット
  +・CLK端子をHighにセット ここでシフトレジスタの0ビット目に①の値がセットされます
  +    つまり 00000000 0000000 がMAX7219のシフトレジスタに入ってま
  +・CLK端子をLowにセット
  +・14ビット目の値をDINにセット
  +・CLK端子をHighにセット ここでシフトレジスタがシフトし②が0ビット目に入ります
  -  つまり 00000000 000000①② が入ってます
      これを繰り返して 16ビットすべて送信したら

  LoadをHighにセットします

  この瞬間シフトレジスタの値が 指定されてたレジスタに反映されます。

この流れを、プログラムに組んでやれば、基本的なデータの送信ができます。この送信の手順は、

のデータシートに記載のあるタイミング図をみればいいみたいですが、いままで、この意味がよく分かり
ませんでした。今となって、やっとその意味が分かりました。

このデータ送信も、arduinoだとSPI(シリアル通信)のライブラリーがあるので、簡単にできてしまうよう
なので、ちょっと、びっくりですね。

スマホ用の画面が崩れるーーWP

CやVBAのコードを見やすくする Highlighting Code Block というプラグインをインストールしました。
おかげ様でコード等は見やすくなりましたが,困った問題が一つ発生です。
それは,今まで,何のても加えずに,スマホ等でもそれに応じた画面の表示ができていたのですが,PCの画面
が表示されるようになりました。
このWPも多少手を加えて,投稿記事を~で囲めばPC用の表示に,で囲めばスマホ用の画
面になるようにしていましたがそれもできなくなりました。
あれこれやりましたが,PCとスマホ用で使用するテーマを変更するために,Multi Device Switcher という
プラグインを導入しました。PCの画面とは,イメージが違ってしまいますが,今までと同じようにスマホでも
画面の全部が表示できるようになりました。

コードの表示も問題なさそうです。

Arduino PWM 再び (2)

割り込みを使ったPWMのLチカをやりましたが,機能として備わっているPWMもやってみることにしました。
でもがっかりしました。簡単過ぎるのです。

analogWrite(PIN番号,DUTY)

これだけで,できてしまうのです。ただ,analogWriteでは,周波数とかの細かい設定はできないようです。
DUTYは最高が0~255まで,指定できるようです。PICだと,設定値をビット演算して,レジスターに書き
込むのでちょっと面倒です。周波数とかの細かい設定をするには,やはりレジスタをいじるようです。

昨日作った割り込みのPWMと備え付け機能のPWMを使い,LEDをだんだん明るくして,だんだん暗くする
というスケッチを書いて動かしてみました。

include<avr/io.h>
#include <avr/interrupt.h>


int k=0;
int BLUE_LED_PIN = 11;  // PWM出力させるピン番号を指定
int RED_LED_PIN = 13;   //11は備え付け,13は割り込みj
int DUTY = 0;


void setup() {
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(BLUE_LED_PIN, OUTPUT);


  TCCR1A  = 0;
  TCCR1B  = 0;
  TCCR1B = bit(WGM12) | bit(CS11) | bit(CS10); // CTCモードで分周率64
  TIMSK1 = bit(OCIE1A); // 割り込みをタイマー1に設定
  //TCCR1B |= (1 << WGM12) | (1 << CS12);  //CTCmode //prescaler to 256
  OCR1A   = 6-1;
  //TIMSK1 |= (1 << OCIE1A);
}


ISR (TIMER1_COMPA_vect) {
 if(k<255){
    k=k+1;
  }
  else{
    k=0;
  }
  if(k==0){
    digitalWrite(RED_LED_PIN, HIGH);
  }
  if(k==DUTY){
    digitalWrite(RED_LED_PIN, LOW);
  }
}


void loop() {
   while(DUTY<255){//だんだん明るくする
    analogWrite(BLUE_LED_PIN, DUTY);
    DUTY=DUTY+1;
    delay(25);
  }
  delay(500);
   while(DUTY>1){//だんだん暗くする
    analogWrite(BLUE_LED_PIN, DUTY);
    DUTY=DUTY-1;
    delay(25);
  }
  delay(500);
}

ほぼ同じような動作をしますが,割り込みを使った方は,あるタイミングでちらつきます。どのタイミングで
ちらつくのか分かりませんが,多分,カウント等余分な動作をしているからかなと推測します。

赤のLEDが割り込みでの点滅で,青のLEDが備え付け機能を使った点滅です。

Arduino PWM 再び

このところ,Arduinoをいじってます。PICに比べると遙かにわかりやすいです。ただ,PICに比べると,細か
な設定等が難しいのが欠点であるといえば欠点ですが。

今回は,ArduinoにもPWMの機能が備わっていますが,この機能を使わずに割り込みで,PWMを簡易的に実現してみました。PWMを実現するには,単純に,端子をLOWとHIGHTに切り替えることができればいいので,通常は,

   端子をHIGHT
   delay(50)
   端子をLOW

みたいにすれば,たやすく実現できます。ただ,このdelay(50)がちょっと気に入らないので,使わないで
実現できないかと考えた訳です。構想としては,TIMER割り込みの回数を数えて,

   0回目の割り込み→→端子をHIGHT
   n回目の割り込み→→端子をLOW
   規定の回数の割り込みで,また,0から数えるLOW

組み込みのPWMでも,レジスターレベルでカウントして,考え方としては,上記のものと同じ考えでやってる
ようです。

arduinoで,やってみました。LEDがだんだん明るくなると次は次第に暗くなるというスケッチを描いてみまし
た。

#include<avr/io.h>
#include <avr/interrupt.h>
int k=0;
int n=0;
void setup() {
  pinMode(13, OUTPUT);


  TCCR1A  = 0;
  TCCR1B  = 0;
  TCCR1B = bit(WGM12) | bit(CS11) | bit(CS10); // CTCモードで分周率64
  TIMSK1 = bit(OCIE1A); // 割り込みをタイマー1に設定
  //TCCR1B |= (1 << WGM12) | (1 << CS12);  //CTCmode //prescaler to 256
  OCR1A   = 11-1;
  //TIMSK1 |= (1 << OCIE1A);
}


ISR (TIMER1_COMPA_vect) {
 if(k<100){
    k=k+1;
  }
  else{
    k=0;
    digitalWrite( 13, HIGH);
  }
  if(k==n){
    digitalWrite( 13, LOW);
  }
}


void loop() {
   while(n<100){//だんだん明るくする
    n=n+1;
    delay(25);
  }
   while(n>1){//だんだん暗くする
    n=n-1;
    delay(25);
  }
 
}

動作している様子です。時々,ちらつきがあります。LEDで動かしていますが,もしかして,これで,モー
ターを制御するとばたついたりするかもしれません。

お散歩グッズの修理?

このところ,夜にお散歩(ウォーキング)をしています。そのとき,安全面を考えて,名前は分かりませんが
LEDで点滅するグッズを身につけています。

買った時からどうもスイッチの感度が悪く,スイッチを入れるのに,かなり,押し込まないと点灯しませんで
した。
そこで,修理といえるほどではないのですが,分解して,接点をお掃除することにしました。

写真の四つのねじを外して,カバーをとります。

基盤ば見えますので,この基盤を裏返しします。

この基盤にスイッチがあります。押すとペコペコと音がする5mm程度金属がスイッチです。

画像はあまりよくないのですが,この金属のカバー?と基盤の間に隙間がありますので,そこを,エアダス
ターで何回かブローして,接点回復剤で,さらにスプレします。最後にエアダスターで,余分な接点回復剤
をタブローします。電池を入れて,テストして問題なかったので,戻します。

今回は,近くのHCで入手したKUREの2-26を使いましたが,〇MAZONには,専用の回復剤もある
ようですが,どれがいいのかは,わかりません。お掃除?の結果,今までの動作が嘘だったかのように,軽い
力で操作ができるようになりました。本当なら,ペコペコする金属を基盤から外して,接点を掃除した方がい
んでしょうけど,か細い爪で基盤に付いているだけなので,それを曲げて取り外すのが怖くで,基盤にすいた
ままのお掃除でした。

ユーザーフォーム SetFocus VBA エクセル 検索 (2)

間に合わせて作ったVBAが25日の仕事で役に立ちました。いくつか改良点が必要だったので,改良を加えま
した。やはり,複数検索対応が必要で,アクティブセルを目立たせることも使いやすくするためには必要でし
た。どうしようかと思いましたが,リストボックスと組み合わせることで,懸念だった,検索結果の複数項目
を保持することにしました。

上記のようなユーザーフォームで,検索結果をリストボックスに表示するようにしました。結果が単数の場合
はそのまま選択し,複数の場合は,リストボックスで選択するようにしました。
前回・今回のプロシャージャで,使ったのが,Find(keyWord, LookAt:=xlPart) というものですが,これ
は,最初にでてきたものしかヒットしません。前回のプロシャージャでは,FindNext(myCell)との組み合わせ
で,あらかじめ複数検索の対象を把握しておいて,複数検索の対象の場合は,別な検索キーで検索するとい
う,手間をかけてました。リストボックを使うことで,検索結果を全部リストボックスに表示することで,プ
ログラム的にはすっきりしました。検索結果が単数の場合は,リストボックスに表示する必要なないのです
が,複数か単数かの判別をする必要が面倒なので,一律リストボックスに表示して,

複数→選択(手動),単数→プログラムで選択

のようにしました。便利な命令があるのもので,今回のプロシャージャ作成で初めて使いましたが,

sendkeys

というもので,キーボードを押した状態をプログラムで作ることができるものです。今回初めてわかりました
が,もし,以前から分かっていたら,以前作ったプロシャージャももっと楽に作れたかもしれないと思います。
次のような動作をします。ここで使ってる名前は,データ用の架空の名前です。

名前を入力して,リターンキーを押すと,検索結果がリストボックスに表示されると同時に,選択されたセル
が見えるようになります。名前のとなりの数字は,その名前ある行番号です。

ここで矢印キーで選択する項目を移動すると,それにつれて,選択状態になったセルが見えるようになりま
す。選択してリターンキーを押すと,該当する名前のセルが選ばれ,背景が黄色になります。

単数の場合は,リストボックスに表示するのですが,表示と同時にリターンキーを送るので,リストボックは
見えず選択されたなまえの背景が黄色になります。文字の背景をその都度変えているのは,どの項目がアク
ティブになるかの表示でデバック用も兼ねてます。

合わせて,上記のように,アクティブセルの色を変えて,他のセルと区別できるようにしてます。次回,操作
の様子と全プロシャージャを掲載します。

ユーザーフォーム SetFocus VBA エクセル 検索 (3)

動作の様子です。使ってる名前は,データ作成サイトで作成した架空のものです。

以下,プロシャージャの全文です。

 

 

-ThisWorkbook-
Private Sub Workbook_Open()'************************************************
  Application.OnKey "{F3}",   "BK_clere"
End Sub

このサブは,背景色をクリアーする機能を F3キー に割り当てる部分です。

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
  Application.ScreenUpdating = True
End Sub

この部分は,アクティブセルを強調するための記述で,条件付き書式と合わせて設定してます。

-UserForm1-
Dim keyWord As String
Dim myRange As Range
Dim myObj As Range

Private Sub ListBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)'***********************************************
  If KeyCode = vbKeyReturn Then
    If ListBox1.ListCount = 0 Then
      UserForm1.TextBox1.SetFocus
      Exit Sub
    Else
     Range(Cells(ListBox1.List(ListBox1.ListIndex, 1), 4).Address).Interior.ColorIndex = 6 (br /)
     'Rangで単一セルを指定の時はaddressが必要
     Cells(ListBox1.List(ListBox1.ListIndex, 1), 4).Select
     Label1.Caption = "検索結果=" & ListBox1.List(ListBox1.ListIndex, 0)
     ListBox1.Clear
     UserForm1.TextBox1.SetFocus
    End If
  End If
  If KeyCode = vbKeyF1 Then
    Range(Cells(ListBox1.List(ListBox1.ListIndex, 1), 4).Address).Interior.ColorIndex = 0
    Cells(ListBox1.List(ListBox1.ListIndex, 1), 4).Select
    Label1.Caption = "検索結果=" & ListBox1.List(ListBox1.ListIndex, 0)
    ListBox1.Clear
    UserForm1.TextBox1.SetFocus
  End If
End Sub

Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)'*************************** 
  Dim K As Integer   
  keyWord = TextBox1.Text

  If KeyCode = vbKeyF1 Then'F1が押されたとき
    ActiveCell.Interior.ColorIndex = 0
    Label1.Caption = "検索結果の削除"
  End If

  If KeyCode = vbKeyReturn Then 'リターンキーが押されたとき
    If keyWord <> "" Then

      K = fukusu_kensaku(keyWord)

      If K > 1 Then
        Label1.Caption = "検索結果=" & "複数該当"
        UserForm1.ListBox1.ListIndex = 0
      Else
        Label1.Caption = "検索結果=" & "一人該当"
        UserForm1.ListBox1.ListIndex = 0
      End If
    UserForm1.TextBox1.Text = ""
    End If

   UserForm1.TextBox1.SetFocus
  End If
End Sub

Private Sub UserForm_Initialize()'************************************************ 
  TextBox1.Text = ""
  With ListBox1
    .ColumnCount = 2
    .ColumnWidths = "120;50"
  End With

  With TextBox1
    .BackColor = RGB(204, 255, 255)
  End With
End Sub

Private Sub UserForm_Activate()'************************************************ 
  UserForm1.TextBox1.SetFocus
End Sub

Private Sub TextBox1_Change()'************************************************ 
  keyWord = TextBox1.Text
End Sub

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)'************************************************ 
  With TextBox1
    .BackColor = RGB(255, 255, 255)
  End With
  With ListBox1
    .BackColor = RGB(204, 255, 255)
  End With
End Sub

Private Sub ListBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
'*********************************************
  With TextBox1
    .BackColor = RGB(204, 255, 255)
  End With
  With ListBox1
    .BackColor = RGB(255, 255, 255)
  End With
End Sub

Private Sub ListBox1_Change()'***********************
  If ListBox1.ListCount >= 1 Then
    Cells(ListBox1.List(ListBox1.ListIndex, 1), 4).Select
  End If
End Sub

-Module1-
Sub macro2()'***********************
  UserForm1.Show vbModeless
End Sub

Function fukusu_kensaku(key_word As String) As Integer'***********************
  Dim myRange As Range
  Dim myObj As Range
  Dim keyWord As String
  Dim K As Integer
  Set myRange = Range(Range("D2"), Cells(Rows.Count, 4).End(xlUp))
  keyWord = key_word
  Set myObj = myRange.Find(keyWord, LookAt:=xlPart)
  K = 0

  If myObj Is Nothing Then
    MsgBox "'" & keyWord & "'はありませんでした"
    Exit Function
  End If
  Dim msg As String
  Dim myCell As Range
  Set myCell = myObj
  Do
    K = K + 1

    With UserForm1.ListBox1
      .AddItem myCell.Value
      .List(K - 1, 1) = myCell.Row
    End With
    myCell.Offset(0, -3).Value = keyWord & K '■■■■欄外に記入

    Set myCell = myRange.FindNext(myCell)
  Loop While myCell.Row <> myObj.Row

  If K > 1 Then
    UserForm1.ListBox1.SetFocus
    Call SendKeys("{DOWN}")
    Call SendKeys("{UP}")
  End If
  If K = 1 Then
    UserForm1.ListBox1.SetFocus
    Call SendKeys("{Enter}")
  End If
  fukusu_kensaku = K
End Function

Private Sub BK_clere()'***********************
  ActiveCell.Interior.ColorIndex = 0
End Sub

Public Sub SendKeys(Keys As String, Optional Wait As Boolean = False)'***********************
  Static w As Object '// WshShellオブジェクト
// WshShellオブジェクトが生成されていない場合
  If w Is Nothing Then
'// WshShellオブジェクトを生成
    Set w = CreateObject("WScript.Shell")
  End If

  Call w.SendKeys(Keys, Wait)
End Sub

 

ユーザーフォーム SetFocus VBA エクセル 検索 (1)

お手伝いの仕事?を楽にするため,また,簡単なVBAを作りました。簡単にできるかと思ったのですが,意外
に難航。なかなか思った動作をしてくれません。意図した動作とは,


のようなユーザーフォームで,クリックをしなくても,テキストボックスに入力できるようにするというもの
です。入力できるようにするには,TextBox1.SetFocus という表現をするのですが,どう書き換えても入力
できるようになりませんでした。ネットでくぐってもこの SetFocus のトラブルは結構あるみたいで,いく
つも出てきますが,明確な解決法には,あたりませんでした。 

最初 Private Sub TextBox1_Change() というイベントに関係することを記載していましたが,だめでした。

そこで,

Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)

のイベント処理のところに書いたら,やっと思った動作ができました。
SetFocus の命令は,どこに書いても正しい動作をするのではない,ということが,おぼろげながら分かりま
した。

思った動作とは,

 ユーザフォームを自動で表示(クリックしなくても,テキストボックスに入力できる状態に)
 入力後所定の動作が終わったら,また,テキストボックスに入力できる状態に

ということで,次のようなコードで,思った動作ができました。

Dim keyWord As String
Dim myRange As Range
Dim myObj As Range

Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    Set myRange = Range("D5:D98")
    keyWord = TextBox1.Text
    If KeyCode = vbKeyReturn Then
    Set myObj = myRange.Find(keyWord, LookAt:=xlPart)
    Label1.Caption = "検索結果=「" & myObj.Offset(0, 0).Value & "」" & myObj.Row & "行目"
    myObj.Offset(0, -3).Interior.ColorIndex = 6
    UserForm1.TextBox1.Text = ""
    UserForm1.TextBox1.SetFocus
    End If
    If KeyCode = vbKeyF1 Then
    myObj.Offset(0, -3).Interior.ColorIndex = 0
    Set myObj = Nothing
    Label1.Caption = "検索結果="
    UserForm1.TextBox1.Text = ""
    UserForm1.TextBox1.SetFocus
    End If
   End Sub

Private Sub UserForm_Initialize()
    TextBox1.Text = ""
End Sub

Private Sub UserForm_Activate()
    UserForm1.TextBox1.SetFocus
End Sub

Private Sub TextBox1_Change()
    keyWord = TextBox1.Text
End Sub

 

やっていることは,単に,テキストボックに検索する文字を入力して,検索後,あれば,あった場所の左側の
背景の色を変えるということで,なんのことはありません。エンターキーを押すと,検索して,F1 を押すと
直前に変えた背景をもとに戻すという,単純な動作です。

ただ,今回のものは,検索の対象が,複数ある場合には,対応していません。複数検索に対応させるには,検
索自体はそれほど複雑ではないのですが,背景色を変える対象も複数になるので,それをもとにに戻すとなる
と,背景を変えた場所を何らかの形で記憶していないとだめで,プロシャージャが複雑になりますので,今回
はやめようかと思います。