質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

7057閲覧

VBAでCRC-16実現させたい。

pokemonta

総合スコア170

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/04/19 06:13

編集2020/04/19 14:59

PythonでCRC-16のサンプルプログラムがありましたので
VBAでコンバートさせました。しかしながら以下のエラーが発生いたします。
「For Eachは、コレクションオブジェクトまたは配列でのみ繰り返しを実行します。」
また、"\x01\x04\x00\x00\x00\x01"を1バイトずつ取得したいのですが
inputdataには、10進数の値が入ります。(1310721)
どこを改善すればよろしいでしょうか
crc = &HFFFFも失敗
crcがbyte型なので16bitの初期化ができないし

python

1# -*- coding: utf-8 -*- 2 3# エラーチェック以外のクエリ 4command = b"\x01\x04\x00\x00\x00\x01" 5 6# 最初のCRCレジスタ値をFFFFhに設定 7crc_registor = 0xFFFF 8for data_byte in command: 9 # CRCレジスタとデータバイトのXOR 10 tmp = crc_registor ^ data_byte 11 # シフト回数を記憶 12 shift_num = 0 13 # シフトが 8回になるまで繰り返す 14 while(shift_num < 8): 15 if(tmp&1 == 1): # 桁あふれが1なら 16 tmp = tmp >> 1 17 shift_num += 1 18 tmp = 0xA001 ^ tmp 19 else: 20 tmp = tmp >> 1 21 shift_num += 1 22 # 計算結果をcrc_registorにセット 23 crc_registor = tmp 24# 計算結果をbytes型へ変換 25crc = crc_registor.to_bytes(2, 'big') 26 27# 結果を表示 28print(crc)

VBA

1 2'CRC16計算 3Private Sub CommandButton1_Click() 4 Dim anser As Byte 5 Dim inputdata As Long 6 7 'b"\x01\x04\x00\x00\x00\x01" 8 inputdata = &H140001 9 anser = CRC16_Calculate(inputdata) 10 11End Sub 12 13 14'CRC-16 15Public Function CRC16_Calculate(ByVal str As Long) As Byte 16 Dim crc As Byte 17 Dim i As Integer 18 Dim DecByte As Byte 19 Dim tmp As Byte 20 21 crc = &HFFFF 22 ibm16 = &HA001 23 24 For Each cel In str 25 DecByte = cel.Value 26 tmp = crc Xor DecByte 27 28 For i = 1 To 8 29 '1ビット目の比較 30 If ((tmp And &H1) = 1) Then 31 '右に1bitシフト 32 tmp = tmp \ (2 ^ 1) 33 i = i + 1 34 tmp = ibm16 Xor tmp 35 Else 36 tmp = tmp \ (2 ^ 1) 37 i = i + 1 38 End If 39 40 Next 41 CRC16_Calculate = tmp 42 Next 43 44End Function 45

リンク内容

リンク内容

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2020/04/19 06:17

「全く動きません」とはどういう状態ですか?
pokemonta

2020/04/19 06:39

まず、Set inputdata = &H140001で 「オブジェクトが必要です」。setを定義しているのに また、&H140001をForで1byteずつ取得する方法もわかりません。
meg_

2020/04/19 09:11

エラーが出ているのであれば、コードのどの箇所でどのようなエラーが出ているのかを質問に追記してください。この欄に書いても見る人は少ないので。
sazi

2020/04/19 10:02

色々と問題があります。先ずはコンパイルエラー取らないと話になりません。
guest

回答1

0

ベストアンサー

【追記】一部実装してみました。

Python

1command = b"\x01\x04\x00\x00\x00\x01" 2crc_registor = 0xFFFF 3 4for data_byte in command: 5 tmp = crc_registor ^ data_byte

VBA

1command = &H140001 2crc_registor = &HFFFF& 3 4For i = 1 To Len(Hex(command)) 5 data_byte = Val("&H" & Mid(Hex(command), i, 1) & "&") 6 tmp = crc Xor data_byte 7Next i

inputdataに値を格納する際にSetは不要です。
質問のコードではinputdataByte型の変数なので、格納できるのは0~255の範囲の単精度の正の数値となります。そのためinputdata = &H140001はオーバーフローします。


"\x01\x04\x00\x00\x00\x01"を1バイトずつ

配列にしてはどうでしょうか?

VBA

1Dim a(6) As Byte 2 3a(1) = 1 4a(2) = 4 5a(3) = 0 6a(4) = 0 7a(5) = 0 8a(6) = 1

投稿2020/04/19 09:32

編集2020/04/19 16:01
meg_

総合スコア10580

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pokemonta

2020/04/19 11:31

ご指摘の通り、オーバフロー発生していました。そこに気がつきませんでした。
pokemonta

2020/04/19 14:23

pythonだと以下の構文を書けましたが、VBAだと連続する16進数の表現方法がわかりません。 b"\x01\x04\x00\x00\x00\x01" それをどうやって一文字ずつ取得するのかも
pokemonta

2020/04/19 23:34

crc_registor = &HFFFF&でオーバフロー発生しませんか?
meg_

2020/04/20 01:06 編集

command、crc_registorはLong型にしたかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問