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

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

新規登録して質問してみよう
ただいま回答率
85.31%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

2回答

700閲覧

選択した範囲の半角数字を全角数字に変換

Noeru

総合スコア1

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

0クリップ

投稿2023/08/30 11:55

実現したいこと

選択した範囲の文字列の半角を全角に変換したい
下記の画像はサンプルです。
イメージ説明

前提

セル内に画像の含まれたスプレッドシートを使用しています。
今までは置換を利用して半角数字を全角数字に変換していましたが、如何せん時間かかるのでGASを利用したいと思ってます。

発生している問題・エラーメッセージ

セル内に画像が含まれている所為か、画像がCellImageに変換されてしまう。
画像は変換されずに、文字列のみ変換したいです。
下記の画像はGAS実行後になります。
イメージ説明

該当のソースコード

function convert_digit_hankaku_to_zenkaku() { // UIを取得 const ui = SpreadsheetApp.getUi(); // 実行を確認する const response = ui.alert('選択範囲にある「半角数字」を「全角数字」に変換します。\nよろしいですか?', ui.ButtonSet.OK_CANCEL); // キャンセルが押されたらスクリプトを終了する if (response == ui.Button.CANCEL) { return; } // 現在開いているスプレッドシートオブジェクトを取得 const ss = SpreadsheetApp.getActiveSpreadsheet(); // 開いているシートオブジェクトを取得 const sheet = ss.getActiveSheet(); // 変換用の全角数字リストを準備 const zenkaku = ['0','1','2','3','4','5','6','7','8','9']; // 変換用の半角数字リストを準備 const hankaku = ['0','1','2','3','4','5','6','7','8','9']; // 選択中のrangeオブジェクトを取得 const range = sheet.getActiveRange(); // 選択中セルの値を取得 const values = range.getValues(); // 取得したセルを1つずつループして変換していく for (let i = 0; i < values.length; i++) { // 行のループ for (let j = 0; j < values[i].length; j++) {// 列のループ // セルの文字1文字ずつ分割して配列にする。数値型だとsplit出来ないのでStringに変換してから。 let text_split = String(values[i][j]).split(''); // 置換後の文字を入れておく変数を用意 let text_converted = []; // セル内の文字を1文字ずつ変換していく for (let i = 0; i < text_split.length; i++) { // 数字が半角リストの何番目にマッチするか探し、その同じkeyの全角数字を取得 let char_converted = zenkaku[hankaku.indexOf(text_split[i], 0)]; if (char_converted == null) { // ヒットしなかった場合は変換せずにそのまま追加する text_converted.push(text_split[i]) } else { // ヒットした場合は変換後の全角数字を追加する text_converted.push(char_converted); } } // 変換後文字列が入った配列を連結する values[i][j] = text_converted.join(''); } } // セルへ書き込む range.setValues(values); }

試したこと

GAS初心者の為、このコードを文字列のみ変換出来るよう条件分岐しようかと思いましたがコードが書けず断念致しました。

要望

なぜこの不具合が起きるのか原因を教えて頂きたいです。
またGAS初心者の為、改善後のコードを書いて下さると非常に助かります。
よろしくお願いします。

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

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

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

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

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

guest

回答2

0

画像があるセルの値にはCellImageというオブジェクトが格納されています。
このCellImgeというオブジェクトをString(values[i][j])にて文字列としたときに"CellImage"という文字列になってしまいます。
この"CellImage"という文字列を変換後のデータとして書き戻しているので結果が画像から文字列に変わっているというのが今回の現象の原因です。

なのでint32_tさんの回答のように数値以外は変換しないというような感じで変換する型、変換しない型を決めてif文で判断しましょう。

投稿2023/08/31 00:45

YAmaGNZ

総合スコア10542

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

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

Noeru

2023/08/31 02:11

回答ありがとうございます。 やはりオブジェクトが文字列かCelllmageで不具合がおきていたのですね。
guest

0

シートから取ってきた値が数値ではないなら何もしてはいけないので、「セルの文字1文字ずつ分割」の前に

js

1if (typeof(values[i][j]) != 'number') 2 continue;

を入れるのはいかがでしょうか。

投稿2023/08/30 23:58

int32_t

総合スコア21927

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

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

Noeru

2023/08/31 02:07

回答ありがとうございます。 ご指摘のとおり、コードを追加して実行してみましたがエラーが出てしまいます。 何故だか理由は分かりますでしょうか? ``` function convert_digit_zenkaku_to_hankaku() { // UIを取得 const ui = SpreadsheetApp.getUi(); // 実行を確認する const response = ui.alert('選択範囲にある「半角数字」を「全角数字」に変換します。\nよろしいですか?', ui.ButtonSet.OK_CANCEL); // キャンセルが押されたらスクリプトを終了する if (response == ui.Button.CANCEL) { return; } // 現在開いているスプレッドシートオブジェクトを取得 const ss = SpreadsheetApp.getActiveSpreadsheet(); // 開いているシートオブジェクトを取得 const sheet = ss.getActiveSheet(); // 変換用の全角数字リストを準備 const zenkaku = ['0','1','2','3','4','5','6','7','8','9']; // 変換用の半角数字リストを準備 const hankaku = ['0','1','2','3','4','5','6','7','8','9']; // 選択中のrangeオブジェクトを取得 const range = sheet.getActiveRange(); // 選択中セルの値を取得 const values = range.getValues(); // 取得したセルを1つずつループして変換していく for (let i = 0; i < values.length; i++) { // 行のループ for (let j = 0; j < values[i].length; j++) {// 列のループ // セルの文字1文字ずつ分割して配列にする。数値型だとsplit出来ないのでStringに変換してから。 if (typeof(values[i][j]) != 'number') continue; let text_split = String(values[i][j]).split(''); // 置換後の文字を入れておく変数を用意 let text_converted = []; // セル内の文字を1文字ずつ変換していく for (let i = 0; i < text_split.length; i++) { // 数字が半角リストの何番目にマッチするか探し、その同じkeyの全角数字を取得 let char_converted = zenkaku[hankaku.indexOf(text_split[i], 0)]; if (char_converted == null) { // ヒットしなかった場合は変換せずにそのまま追加する text_converted.push(text_split[i]) } else { // ヒットした場合は変換後の全角数字を追加する text_converted.push(char_converted); } } // 変換後文字列が入った配列を連結する values[i][j] = text_converted.join(''); } } // セルへ書き込む range.setValues(values); } ```
int32_t

2023/08/31 02:35

> エラーが出てしまいます。 どのようなエラーですか?
Noeru

2023/08/31 03:14 編集

このようなエラーが出てしまいます。 エラー Exception: Service error: Spreadsheets convert_digit_zenkaku_to_hankaku @ コード.gs:72
int32_t

2023/08/31 04:36

エラーメッセージはそれですべてですか? コードの72行目はどの行ですか?
Noeru

2023/08/31 04:59

エラーメッセージはこれで全てです。 先程返答したコードの最後の行の1つ上が72行目になります。 // セルへ書き込む range.setValues(values); }
int32_t

2023/08/31 07:23

情報ありがとうございます。 ちょっと調べてみたところ、getValues() で取得した画像セルをそのまま setValues() でセットするとエラーになるようです。 であれば、2重ループが終わってから range.setValues(values) でいっぺんに値を更新するのではなく、ループの内側で text_converted.join('') の結果を1つずつ setValue() する必要がありそうです。
Noeru

2023/08/31 08:00

色々調べて頂きありがとうございます。 ここまで画像セルが不具合に影響してくるとは…って感じですね。 ループの内側でどのようにsetValueすべきかが分かりかねます。 もし宜しければ修正後のコードを書いてくださると助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問