重複配列の取得と、各配列ごとの平均値取得(動的配列、UBound、Dictionary 使用)

‘重複品番のうち、価格が同じはOKと判断する。
‘配列に重複品番を格納
Dim Dic As Object, buf As String
Dim Arr() As String: ReDim Arr(0) ‘Index 0で初期化
Dim sum下代 As Currency, ave下代 As Currency
Dim rowNo As Long, i As Long, k As Long, m As Long
Dim LastRow As Long

‘ s1 = “新規メニュー予定”
LastRow = Worksheets(s1).Cells(Rows.Count, 14).End(xlUp).Row ‘N列(モダンブルー品番)最終行番号取得

Set Dic = CreateObject("Scripting.Dictionary")

With Worksheets(s1)
    For i = 4 To LastRow

        If .Range("A" & i) = "重複" Then

            buf = .Range("N" & i).Value         ''セルの値を変数bufに格納する
            If Not Dic.Exists(buf) Then     ''まだ登録されていなかったら…

                Dic.Add buf, buf  ''セルの値を連想配列に登録する

                'Arrへの格納時に、添え字の数値指定ではなくUboundで最大要素に追加する。
                 Arr(UBound(Arr)) = .Range("N" & i).Value

                 '拡張
                 ReDim Preserve Arr(UBound(Arr) + 1)

            End If

        End If

    Next i

    '1つ余分に作ってしまうので削除
    ReDim Preserve Arr(UBound(Arr) - 1)

    MsgBox Dic.Count & "件の品番が重複しています。"

    '重複品番の各品番ごとに下代の平均値を算出し、それに下代の金額が合致していたら問題ないと判定し、「重複」⇒「OK」に変更する
    For i = 0 To Dic.Count - 1

        sum下代 = 0
        m = 0
        For k = 4 To LastRow
            '重複品番のある行数を取得
            If .Range("N" & k).Value = Arr(i) Then
                '下代(U列)の合計を算出
                sum下代 = sum下代 + .Range("U" & k).Value
                m = m + 1
            End If
        Next k

        ave下代 = sum下代 / m

        For k = 4 To LastRow
            '重複品番のある行数を取得
            If .Range("N" & k).Value = Arr(i) And .Range("U" & k).Value = ave下代 Then
                .Range("A" & k).Value = "OK"

                '背景色とフォントカラーを通常に戻す。
                .Range("A" & k).Interior.Color = RGB(255, 255, 255)
                .Range("A" & k).Font.Color = RGB(0, 0, 0)
                .Range("Q" & k).Interior.Color = RGB(255, 255, 255)
                .Range("R" & k).Interior.Color = RGB(255, 255, 255)
                .Range("U" & k).Interior.Color = RGB(255, 255, 255)


            End If
        Next k

    Next
    MsgBox "重複品番については、下代の金額が合致していた場合、" & vbCrLf & "問題ないと判定しますので、A列を「OK」に変更いたします。"

End With

'-----検証----

Debug.Print "----"

For i = 0 To UBound(Arr)
    Debug.Print Arr(i)
Next i
Debug.Print "----"

Set Dic = Nothing

参考文献
https://thom.hateblo.jp/entry/2015/03/19/213019
★動的配列:UBound
http://officetanaka.net/excel/vba/function/UBound.htm

SQL Server にTCP/IP接続する方法

SQL Server 構成マネージャ を起動します。


※注意:SQL Server 構成マネージャーは Microsoft 管理コンソール プログラムのス
ナップインであり、スタンドアロン プログラムではないため、
新しいバージョンの Windows では、 SQL Server 構成マネージャーは
アプリケーションとして表示されません。
Windows 10:>
SQL Server 構成マネージャーを開くには、 スタート画面で、
「SQLServerManager13.msc」( SQL Server 2016 (13.x)の場合) と入力します。
他のバージョンの SQL Server 場合、13 を対応する数値に置き換えます。
SQLServerManager13.msc をクリックすると、構成マネージャーが開きます。
スタート画面やタスク バーに構成マネージャーをピン留めするには、
SQLServerManager13.msc を右クリックして、 [ファイルの場所を開く] をクリック
します。 エクスプローラーでは、SQLServerManager13.msc を右クリックし、
[スタート画面にピン留め] または [タスクバーにピン留め] をクリックします。

Windows 8:>
SQL Server 構成マネージャーを開くには、検索チャームの [アプリ] で、
「SQLServerManager<バージョン>.msc」(「SQLServerManager13.msc」など) と
入力し、Enter キーを押します



ツリー表示部から[ SQL Server ネットワークの構成 ] - [ SQLEXPRESS のプロトコル ](インスタンス名) をクリックします。
右ペインにプロトコルの一覧が表示されますので[ TCP/IP ] を右クリックして「有効化」を選択します。

https://www.projectgroup.info/documents/MSSQL/MSSQL-20120002.html


SQLの論理値は3(3値論理)

通常のプログラミング言語の論理値:True,False
SQLの論理値           :True,False,Unknown

●SQLは第三の値Unknownを持つ
●NULLについては、2種類ある
①未知(Unknown)
⇒値でも変数でもない。そこに値がないことを示すための
視覚的マーク、目印にすぎない。
②適用不能(Not Applicable)
⇒「N/A」
 不明(サングラスをかけた人の目の色)ではなく、
    無意味(冷蔵庫の目の色⇒冷蔵庫に目の色という属性は適用不能)

●SQLにはNULLは1種類しか存在しない⇒①Unknown

●なぜ、「=NULL」ではなく、「IS NULL」と書かなければならないか?
⇒NULLに比較述語(=,>,<)を用いると、結果がUnknownになるから。
※比較述語が適用できるのは値のみであり、NULLは値でも変数でもない。
クエリの結果として選択されるのは、WHERE句の条件評価がtrueになる行のみで、false、unknownの行は選択されない。

<Unknownに評価される式>
・1 = NULL
・2 > NULL
・3 < NULL
・4 <> NULL
・NULL = NULL
・NULL > NULL
・NULL < NULL
・NULL <> NULL

「IS NULL」⇒「IS」が述語で、「NULL」が値とみられがちだが、「IS NULL」で1つの述語とみなすべき。
※SQLには、「IS TRUE」,「IS FALSE」があるが、これとは別の構造を持つ述語として考える。

ANDTrueUnknownFalse
TrueTUF
UnknownUUU
FalseFUF

ANDの場合の優先順位 : False > Unknown > True

ORTrueUnknownFalse
TrueTUT
UnknownUU U
FalseTUF

ORの場合の優先順位 :  True  > Unknown >  False

既に開いているフォーム(フォーム1)に対し、フォーム2から値を渡す(住所入力補助フォーム)

https://hosopro.blogspot.com/2017/09/access-vba-form-property.html

フォーム1>

‘メンバ変数
Private mRetnValue As String

‘プロパティ
Public Property Let RetnValue(ByVal Value As String)
mRetnValue = Value
End Property

Public Property Get c() As String
RetnValue = mRetnValue
End Property


Private Sub buttonOpen_Click()

mRetnValue = ""

DoCmd.OpenForm "フォーム2", acNormal, , , , acDialog

'フォーム2で選択した値をテキストボックスに表示
Me.textMessage.Value = mRetnValue

End Sub

フォーム2>

Private Sub buttonOK_Click()

Form_フォーム1.RetnValue = Me.comboFruits.Value

DoCmd.Close acForm, Me.Name

End Sub

デザインビューではコントロールが表示されるのに フォームビューで表示されない

表示されるレコードがなく、追加もできない(=新規レコードの枠が表示されない)状態
の場合、フォームビューの詳細領域にあるコントロールは、全て表示されなくなります。

これはAccessがそういう仕様になっているようなのでどうしようもないのですが、
詳細領域ではなくフォーム ヘッダ/フッタに設置したコントロールであれば表示は
されるので、表示レコードがない場合にも表示が必要なコントロール(フォームを閉じたり
表示を切り替えるコマンドボタンや、フォームの抽出条件を指定するテキストボックス等)
はフッタ/ヘッダに移動する、といった回避方法があります。

※本来表示させるレコードがない状態で、詳細領域のコントロールを強引に表示させる
  には、フォームのプロパティシートの『データ』タブで、『レコードセット』の設定を
  「ダイナセット (矛盾を許す)」にするという手もあります。
  但し、変な形でレコード編集がされてしまう危険性が生じますので、お勧めはできません。

参考
http://oshiete1.goo.ne.jp/qa3371589.html
http://oshiete1.goo.ne.jp/qa3028994.html

USBプリンタサーバー  設定

①IPアドレスの設定
・ ネットワーク上のIPアドレスを確認する
 IP アドレスの存在検出について
ping 192.168.1.1
arp -a
ネットワーク上のすべての IP アドレスを検出する
for /L %i in (1,1,254) do ping -w 500 -n 1 192.168.1.%i > nul && arp -a 192.168.1.%i
・ プリントサーバーにIPアドレスを振る
 (必要な情報)
IPアドレス
サブネットマスク
ゲートウェイアドレス

    ※メーカーによっては、ユーティリティのダウンロードが必要        
IODATAオンラインマニュアル            https://www.iodata.jp/lib/manual/etx-ps_u2-20091224/htm/setup01.htm
BUFFALOオンラインマニュアル           https://www.buffalo.jp/support/faq/detail/884.html

②PCにプリントサーバーのドライバをインストール?

③プリンターの設定とテスト印刷

https://www.akakagemaru.info/port/windows10-ipaddress.html

重複行のレコードに連番を振る

 '同じ製品番号が存在する場合は、行番号のフィールドに連番を振る。(重複なしは"1"とする)
strSQL = "SELECT 製品コード, 行番号 FROM W_製品添加物 ORDER BY 製品コード" '製品コードでソートする
Set rsW = DF_AdoNewRecordset(strSQL, adOpenStatic)

strCode = ""  '重複グループの変わり目を判定する変数
n = 1

If rsW.RecordCount > 0 And rsW.EOF = False Then
    Do Until rsW.EOF

        '製品コードが変わったとき
        If rsW!製品コード <> strCode Then
            n = 1
        End If
        '連番挿入
        rsW!行番号 = n
        '判定用の変数の値を更新
        strCode = rsW!製品コード
        '連番をインクリメント
        n = n + 1
        rsW.Update

        rsW.MoveNext
    Loop
End If
【参照】https://blog.goo.ne.jp/pc_college/e/9af70f574b22701225611def111c68be#_=_


このほか、Dcount関数を使った方法もあるが、上記がすっきりと早い!
【参照】https://hatenachips.blog.fc2.com/blog-entry-428.html
連番: DCount("ID","Tbl1","Group1=" & [Group1] & " AND Group2=" & [Group2] & " AND (Data1='" & [Data1] & "' AND ID<=" & [ID] & " OR [DATA1]<'" & [Data1] & "')")

(エラー:3342)サブクエリ ‘<サブクエリ名>‘ のメモ型または OLE オブジェクト型のデータが正しくありません。

サブクエリはメモ型 (Memo) または OLE オブジェクト型 (OLE Object) のデータを返せないため、式の中でメモ型 (Memo) または OLE オブジェクト型 (OLE Object) のデータと比較することはできません。

<対処方法>

データのフィールドサイズが255文字を超える場合、「長いテキスト」(メモ型)でフィールドを定義するけれど、このデータを活用しようとしてサブクエリでSELECTするとエラーが起きる。

SQLでUPDATEするときに、サブクエリとしてSELECT文で値を抽出せずに、別に、Dlookup関数等で、値を取得して代入する。

【WEHER句】の変数が文字列型
⇒ DLookup(“[更新日]”, “[Aテーブル]”, “[実施日]='” & last_date &”‘”)
【WEHER句】の変数が数値型
⇒ DLookup(“成分”, “TB_製品”, “行番号 = ” & lng行番号)