C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: 【VBA】エクセルデータのコピーについて


(過去ログ 173 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■99751 / inTopicNo.1)  【VBA】エクセルデータのコピーについて
  
□投稿者/ 白音 (1回)-(2022/05/24(Tue) 10:10:38)

分類:[その他の言語] 

2022/05/24(Tue) 10:14:57 編集(投稿者)

ありきたりのファイル読み込みです。

Dim FileData as Variant
Set wb = Workbooks.Open(FilePath)
Set ws = wb.Worksheets(SheetNo)
FileData = ws.UsedRange
wb.Close
Set ws = Nothing
Set wb = Nothing

wbが開かれている状態で
例えばあるセルに【765432123456】という文字列が表示されています。
var をウォッチしても表示は同じく【765432123456】です。
型は[Variant/String] です。
このデータをシートに表示させようと以下の処理を行うと

Dim maxrow As Long: maxrow = UBound(var, 1) '最大行数を取得する
Dim maxcol As Long: maxcol = UBound(var, 2) '最大列数を取得する
mysheet.Range("A1").Resize(maxrow, maxcol) = var


表示されたセルに表示されるのは
【7.65432E+11】です。ただし、セルをクリックしたときにエクセルの
上部に表示される値は【765432123456】です。

セルの書式設定は【標準】です。
Workbooks.Open で開いたときのファイルも同じくそのセルは【標準】です。

もちろん
mysheet.Range("A1").Resize(maxrow, maxcol) = var
を行う前に mysheet の該当するセルの書式設定を【文字列】に
変更しておくとセルの表示が【765432123456】になります。
なので、最悪セルの書式設定を【文字列】に変えるしかないのですが

書式設定が同じ標準であっても
【765432123456】で表示される場合と【7.65432E+11】で表示される場合があるのはなぜでしょうか。
また、手動にてコピー貼り付けを行った場合は【765432123456】のままで【7.65432E+11】には
ならないのはなぜでしょうか?

【追記】
セルの書式を変更しなくても、コピー元ファイルのシートの状態を
そのままコピーしてくる方法はあるのでしょうか?

以上よろしくお願いいたします。

引用返信 編集キー/
■99753 / inTopicNo.2)  Re[1]: 【VBA】エクセルデータのコピーについて
□投稿者/ radian (40回)-(2022/05/24(Tue) 11:09:04)
> 書式設定が同じ標準であっても
> 【765432123456】で表示される場合と【7.65432E+11】で表示される場合があるのはなぜでしょうか。
> また、手動にてコピー貼り付けを行った場合は【765432123456】のままで【7.65432E+11】には
> ならないのはなぜでしょうか?

[XL2002]セルの数値が指数表示になる条件]
https://support.microsoft.com/ja-jp/topic/-xl2002-%E3%82%BB%E3%83%AB%E3%81%AE%E6%95%B0%E5%80%A4%E3%81%8C%E6%8C%87%E6%95%B0%E8%A1%A8%E7%A4%BA%E3%81%AB%E3%81%AA%E3%82%8B%E6%9D%A1%E4%BB%B6-a07d4e43-a58c-c879-066f-4e785f704e81

これに引っかかってるんじゃないですかね。
まあ素直に書式設定しましょう。

引用返信 編集キー/
■99754 / inTopicNo.3)  Re[1]: 【VBA】エクセルデータのコピーについて
□投稿者/ 魔界の仮面弁士 (3373回)-(2022/05/24(Tue) 11:15:36)
No99751 (白音 さん) に返信
> FileData = ws.UsedRange

UsedRange の戻り値は Range 型なので、
 FileData = ws.UsedRange.Value
の方が処理が明確になるかと。

' Set FileData = ws.UsedRange 'Range オブジェクトとして取得
' FileData = ws.UsedRange.[_Default] 'Value プロパティ相当。[_Default] は省略可能


> 書式設定が同じ標準であっても
> 【765432123456】で表示される場合と【7.65432E+11】で表示される場合があるのはなぜでしょうか。

.NumberFormat が "General" の場合、渡したデータが String であったとしても、
日付っぽいデータは Date になり、数字っぽいデータは Double に変化します。

常に文字列として渡したいのであれば、値を代入する前に
 .NumberFormat = "@"
として、文字列型のセルに変更しておきましょう。
(先頭に「'」を付与する方法もありますが、こちらはあまりお奨めしません)


> また、手動にてコピー貼り付けを行った場合は【765432123456】のままで【7.65432E+11】には
> ならないのはなぜでしょうか?
コピー元のアプリケーションは何ですか? メモ帳のテキストを Excel に貼り付けた場合も同様ですか?

クリップボードには、同じデータに対する複数のデータ形式を同時に保持できます。

クリップボードの中身が、書式なしテキスト(たとえば CF_TEXT)のみであったとしたら、
やはり【765432123456】→【7.65432E+11】に変化しますが、
クリップボード内に書式付きデータ(Biff8 など)がある場合はそれが優先されます。


> 例えばあるセルに【765432123456】という文字列が表示されています。
> var をウォッチしても表示は同じく【765432123456】です。
> 型は[Variant/String] です。

使用済みのセルが全くない場合、FileData 変数の中身は Empty になります。

値が単一セルの場合、そのセルのデータに応じて
 [Variant/Empty]
 [Variant/Date]
 [Variant/Double]
 [Variant/String]
とデータ型が変化します。

値が複数セルにまたがる場合は、取得した結果は
FileData(1 To 行数, 1 To 列数) な二次元配列で返されます。
各要素には、各セルの値が入ります。
各要素のデータ型は、セル値に応じて Empty, String, Double, Date と変化します。


状況によってはデータ型を判定するために、
IsArray 関数、IsEmpty 関数、VarType 関数、TypeName 関数などを
併用することもありますね。
引用返信 編集キー/
■99755 / inTopicNo.4)  Re[1]: 【VBA】エクセルデータのコピーについて
□投稿者/ 魔界の仮面弁士 (3374回)-(2022/05/24(Tue) 11:23:32)
No99751 (白音 さん) に返信
> 2022/05/24(Tue) 10:14:57 編集(投稿者)
> 【追記】
> セルの書式を変更しなくても、コピー元ファイルのシートの状態を
> そのままコピーしてくる方法はあるのでしょうか?

書式ごとコピーしては駄目なのでしょうか?

Book1.Worksheets("Sheet1").Range("B2:B4").Copy Book2.Worksheets("Sheet1").Range("C1")
引用返信 編集キー/
■99756 / inTopicNo.5)  Re[2]: 【VBA】エクセルデータのコピーについて
□投稿者/ 白音 (2回)-(2022/05/24(Tue) 11:26:24)
No99753 (radian さん) に返信

返事ありがとうございます。

>
> これに引っかかってるんじゃないですかね。
> まあ素直に書式設定しましょう。
>

もとより条件に引っかかっているのは理解できています。
ただ、コピー元のファイルを開いた場合には標準であるにも関わらず文字列として表示されているのに
プログラムでそのシートのデータをコピーすると文字列ではなくなるというのがわかりません。
同じ条件で違う動きをするというのはあり得ないと思うので何かが違うと思うのですが

後々で 765432123456 の先頭が 765 で始まるセルの検索を行う場合に 7.65432E+11 なので
一致しなくなったり 実際には 0 始まりのデータ 02468 が 2468 となり 024 で検索できなかったのですが

また、素直に書式設定するとしても、列やセルの位置が変わるたびに、
プログラムで列やセルの書式を変更するためのコードを入れるのも面倒だと思うのですが...

ひょっとして
mysheet.Range("A1").Resize(maxrow, maxcol) = var
をしないで、
手動でコピーペーストして問題ないのであれば
同様にVBAでコピーペーストすれば行けるかもしれませんね。

今からちょっと試してみます。


引用返信 編集キー/
■99757 / inTopicNo.6)  Re[2]: 【VBA】エクセルデータのコピーについて
□投稿者/ 魔界の仮面弁士 (3375回)-(2022/05/24(Tue) 11:33:10)
No99755 (魔界の仮面弁士) に追記
> 書式ごとコピーしては駄目なのでしょうか?
> Book1.Worksheets("Sheet1").Range("B2:B4").Copy Book2.Worksheets("Sheet1").Range("C1")

参照数式が含まれいて #REF! になる危険性があるのなら、
PaseteSpecial で値だけ送り込んでみる方法も。

Book1.Worksheets("Sheet1").Range("B2:B4").Copy
Book3.Worksheets("Sheet1").Range("A4").PasteSpecial xlPasteValues


xlPasteValues で送り込んだ時は、貼り付け先のセル書式が General だと
データ型の再判定は行われず、元セルの String / Date / Double が維持されたかと。
引用返信 編集キー/
■99758 / inTopicNo.7)  Re[3]: 【VBA】エクセルデータのコピーについて
□投稿者/ radian (41回)-(2022/05/24(Tue) 11:38:17)
2022/05/24(Tue) 11:48:48 編集(投稿者)

No99756 (白音 さん) に返信
>>これに引っかかってるんじゃないですかね。
>>まあ素直に書式設定しましょう。
>>
>
> もとより条件に引っかかっているのは理解できています。
> ただ、コピー元のファイルを開いた場合には標準であるにも関わらず文字列として表示されているのに
> プログラムでそのシートのデータをコピーすると文字列ではなくなるというのがわかりません。
> 同じ条件で違う動きをするというのはあり得ないと思うので何かが違うと思うのですが

既に魔界の仮面弁士さんが仰っているように、標準セルだとExcelがデータ型を勝手に解釈したりするので、そういう事も有り得ます。
ちなみに、うちの環境で標準セルに765432123456を貼り付けたら指数表示になります。(Excel2013)

>
> 後々で 765432123456 の先頭が 765 で始まるセルの検索を行う場合に 7.65432E+11 なので
> 一致しなくなったり 実際には 0 始まりのデータ 02468 が 2468 となり 024 で検索できなかったのですが
>
> また、素直に書式設定するとしても、列やセルの位置が変わるたびに、
> プログラムで列やセルの書式を変更するためのコードを入れるのも面倒だと思うのですが...

どういう運用を想定しているのか判らないので何とも言えないですが、
最初からシートに書式設定しておくか、書式ごとコピーするとか。
いずれにせよ、そこまで面倒かな?とは思いますが。
データが壊れるリスクを負ってまで、標準セルに固執する必要もないんじゃないでしょうか。
引用返信 編集キー/
■99759 / inTopicNo.8)  Re[1]: 【VBA】エクセルデータのコピーについて
□投稿者/ 大谷刑部 (190回)-(2022/05/24(Tue) 13:00:39)
No99751 (白音 さん) に返信
> 2022/05/24(Tue) 10:14:57 編集(投稿者)

> 表示されたセルに表示されるのは
> 【7.65432E+11】です。ただし、セルをクリックしたときにエクセルの
> 上部に表示される値は【765432123456】です。
>
> セルの書式設定は【標準】です。

表示と実際の値を混同されてませんか?
そもそも、Excelの仕様で標準書式で12桁の整数の値は指数表記です。
セルをクリックしたときに整数表示に変換してユーザーに見せてあげてるだけの話です。
表示上整数表示に見えてる場合でも、標準書式であれば、CSVやタブ区切りテキストファイルで保存すると、中身は指数表示です。

> また、手動にてコピー貼り付けを行った場合は【765432123456】のままで【7.65432E+11】には
> ならないのはなぜでしょうか?

コピー元の書式次第かと。
値だけ貼り付けたら、コピペでも標準書式では指数表示になると思います。

> 【追記】
> セルの書式を変更しなくても、コピー元ファイルのシートの状態を
> そのままコピーしてくる方法はあるのでしょうか?

弁さんの指摘、
>書式ごとコピーしては駄目なのでしょうか?

に尽きるかと思いますが。


で、貼り付け先のシートの書式設定をしておく方法を取る場合は、その数値らしきものがどのようなデータかによると思います。
前0をきちんと残したりしたいコードとか〜番号の場合は文字列しか選択肢がありませんが、
金額項目などむしろ数値データとして扱いたい場合は数値型、通貨型にするしかないと思います。
文字列型にするとExcel上で計算ができなくなるので。




引用返信 編集キー/
■99760 / inTopicNo.9)  Re[1]: 【VBA】エクセルデータのコピーについて
□投稿者/ furu (155回)-(2022/05/24(Tue) 13:41:03)
No99751 (白音 さん) に返信
> 書式設定が同じ標準であっても
> 【765432123456】で表示される場合と【7.65432E+11】で表示される場合があるのはなぜでしょうか。
この挙動ほんとに分かりづらくて私もよく困ります。
特に他から受け取ったファイルで
すべてがG/標準なのにデータは文字列の場合です。
データを手修正したいのに勝手に指数表示や日付に変更されます。

【765432123456】で表示されるのは
   どう入れたか不明だが、データが文字列の場合です。
   セルの編集でEnterキー押すと勝手に【7.65432E+11】に変わります。
【7.65432E+11】で表示されるのは
   普通に765432123456を入れた場合です。


> 【追記】
> セルの書式を変更しなくても、コピー元ファイルのシートの状態を
> そのままコピーしてくる方法はあるのでしょうか?
Copyして値貼り付けで行うと
標準であっても【765432123456】で表示されます。

Range.Copy
Range.PasteSpecial(-4163) //xlPasteValues
引用返信 編集キー/
■99761 / inTopicNo.10)  Re[2]: 【VBA】エクセルデータのコピーについて
□投稿者/ 魔界の仮面弁士 (3376回)-(2022/05/24(Tue) 14:38:55)
No99754 (魔界の仮面弁士) に追記
> ■No99751 (白音 さん) に返信
> .NumberFormat が "General" の場合、渡したデータが String であったとしても、
> 日付っぽいデータは Date になり、数字っぽいデータは Double に変化します。

General 書式でセルの型が自動判定されるのはそういう仕様なので仕方ないとして、
逆に、書式をちゃんと指定していても、表示がおかしくなるケースはありえます。

https://pbs.twimg.com/media/FTf6_bAakAARs_p?format=png&name=900x900

ちなみに一度上記のパターンになると、
 .NumberFormat = "0" をセットすると、【765432123456】表示に変化
 .NumberFormat = "" をセットすると、【7.65432E+11】表示に変化
  そこからさらにセル幅を縮めると、【7.7E+11】などになる
 .NumberFormat = "@" をセットしても、指数表記のまま
という、事後での書式設定がうまく働かなくなるという。
ユーザーが再編集すれば、書式に沿った表示になるのですけれどね。

さらに厄介なことに、同じ操作を行っても、Excel バージョンが異なると
書式変化が行る環境と起こらない環境があるという…。
(General 時の自動判定とは異なり、こちらはおそらく不具合でしょう)
引用返信 編集キー/
■99762 / inTopicNo.11)  Re[2]: 【VBA】エクセルデータのコピーについて
□投稿者/ 白音 (3回)-(2022/05/24(Tue) 15:35:33)
皆さんありがとうございました。

一部理解できない不明な部分はのこったものの

魔界の仮面弁士さんの言う通り書式ごとコピーするように変更しました。
これで、元のエクセルファイルを開いて表示しているのと同じ状態になりました。

みため数字ですが文字列のように表示(セルの左詰め表示)されています。

きっとエクセルの奥深い書式設定等に知らない部分が存在しているのでしょう...

何かありましたらまた、よろしくお願いします。


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -