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

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

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

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

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

ハイパーリンク

ハイパーリンクとは、ハイパーテキストにおいて、複数の文書を結び付ける役割を担う「参照」である。単にリンクとも呼びます

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

0回答

314閲覧

GAS 自作サイト スプレッドシートのハイパーリンクを自作サイトで開けるようにしたい

kazuhiro0626

総合スコア0

Google スプレッドシート

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

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

ハイパーリンク

ハイパーリンクとは、ハイパーテキストにおいて、複数の文書を結び付ける役割を担う「参照」である。単にリンクとも呼びます

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2023/05/08 17:01

編集2023/05/08 17:07

実現したいこと

・GAS経由の自作サイトにハイパーリンクを表示

前提

会社の業務改善として、スプレッドシートの内容をサイト形式で検索できるように作り上げている最中です。
サイトの作成については、色々調べてある程度形にはなりました。
ただその中で、表示元のスプレッドシートにあるリンクが自作サイトで開けるようにならず、苦戦をしております。
おそらくHTML側にコードを追加する必要があるとは感じているのですが、どこに何をいれればいいのかがわかりません。

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

・リンクが文字でクリックができない
(今回やりたいのは、住所のハイパーリンクを開けるようにしたい)
参考のシートはサンプルのためリンクは一か所のみ、本番用にはハイパーリンクが全て入っている状態です。

該当のソースコード

・自作サイト(ここの住所部分をハイパーリンクとして扱いたい)
https://script.google.com/macros/s/AKfycbyxbutqGP7eQVl8iXorTNKllOmA7z2IKKz6UI9NMf9cjPgBDacw2lIn0F-9ckIn/exec

スプレッドシート
https://docs.google.com/spreadsheets/d/e/2PACX-1vSRSUGeYFU04Tx1wNe4zvQ-wmOe2tYyZNMhwelfcJwz0SDFzy-YwO-DgME63i9CvgMdstBiSjWS_-2B/pubhtml?gid=0&single=true

<!DOCTYPE html> <html style="overflow-y:hidden"> <head> <base target="_top"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <style> ::-webkit-scrollbar { background: transparent; height: 10px; width: 8px; } ::-webkit-scrollbar-thumb { border: none; background: #bbb; -webkit-border-radius: 8px; border-radius: 8px; min-height: 40px; } thead th { position: -webkit-sticky; position: sticky; top: -1px; background-color: #ddd; } .btn { position: fixed; width: 50px; height: 50px; color: white; border-radius: 50px; display: flex; justify-content: center; align-items: center; opacity: 0.4; box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3); transition: 200ms; user-select: none; } .btn:hover { opacity: 0.9; } .btn:active { opacity: 1; } </style> </head> <body> <div id="app"> <div style="display: flex;"> <!-- フィルタエリア --> <div style=" width: 300px; height: 100vh; background-color: #fafafa; padding: 0 30px; overflow: auto; "> <!-- タイトル --> <h1 class="title is-4" style="margin-top: 50px;"> <span class="material-icons">filter_list</span> フィルタ </h1> <!-- フォーム --> <template v-for="(key, index) in keys"> <div v-if="!isHidden(key)" style="margin-bottom: 1em;"> <!-- 項目名 --> <label class="label is-small">{{ key.replace(/:.*$/,"") }}</label> <!-- プルダウン(:select["A","B"...] が項目名末尾に付与されていた場合) --> <template v-if="isSelect(key)"> <select v-model="conditions[index]" class="select is-small"> <option value="">選択なし</option> <option v-for="option in getOptions(key)" :value="option">{{ option }}</option> </select> </template> <!-- ラジオボタン(:radio["A","B"...] が項目名末尾に付与されていた場合) --> <template v-else-if="isRadio(key)"> <label for="radio-none"> <input type="radio" id="radio-none" value="" v-model="conditions[index]" /> 選択なし </label> <label v-for="(option, radioIndex) in getOptions(key)" :for="'radio-' + radioIndex"> <input type="radio" :id="'radio-' + radioIndex" :value="option" v-model="conditions[index]" /> {{ option }} </label> </template> <!-- チェックボックス(:checkbox["A","B"...] が項目名末尾に付与されていた場合) --> <template v-else-if="isCheckbox(key)"> <label v-for="(option, checkboxIndex) in getOptions(key)" :for="'checkbox-' + checkboxIndex"> <input type="checkbox" :id="'checkbox-' + checkboxIndex" :value="option" v-model="conditions[index]" /> {{ option }} </label> </template> <!-- テキストボックス(指定なしの場合) --> <input v-else v-model="conditions[index]" type="text" class="input is-small"> </div> </template> <!-- フィルタクリアボタン --> <div @click="initConditions()" class="btn" style="bottom: 30px; left: 220px; background-color: #e85a5a;" > <span class="material-icons">clear</span> </div> </div> <!-- データエリア --> <div style=" max-width: calc(100% - 300px); height: 100vh; padding: 0 50px; overflow: auto; "> <!-- タイトル --> <h1 class="title is-4" style="margin-top: 50px;"> <span class="material-icons">description</span> <?= title ?> </h1> <!-- テーブル --> <table class="table is-striped is-hoverable" style="white-space: nowrap; position: relative;"> <thead> <tr> <th v-for="key in keys">{{ key.replace(/:.*$/,"") }}</th> </tr> </thead> <tbody> <template v-for="record in records"> <tr v-if="checkCondition(record)"> <td v-for="item in record">{{ item }}</td> </tr> </template> </tbody> </table> <!-- ダウンロードボタン --> <div @click="downloadCSV()" class="btn" style="bottom: 30px; right: 30px; background-color: #3a93e8;" > <span class="material-icons">file_download</span> </div> </div> </div> </div> <!-- Vue.js --> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> <script> var app = new Vue({ el: '#app', data: { keys: [], // シートの1行目 records: [], // シートの2行目以降 conditions: [], // 入力した絞込条件 }, mounted: function(){ google.script.run.withSuccessHandler(function(text) { const response = JSON.parse(text) app.keys = response[0]; app.records = response.slice(1); app.records.splice(); app.initConditions(); }).getSheetData(); }, methods: { // フィルタ条件を初期化する initConditions: function(){ this.conditions = app.keys.map((key) => { return app.isCheckbox(key) ? [] : "" }) }, // レコードが全ての絞込条件に合致するかチェックする checkCondition: function(record){ for (let i = 0; i < this.keys.length; i++){ if ( this.isCheckbox(this.keys[i]) ){ if (this.conditions[i].length && !this.conditions[i].includes(record[i])) return false; } else { if ( this.conditions[i] && !record[i].includes(this.conditions[i])) return false; } } return true; }, // CSVファイルをダウンロードする downloadCSV: function(){ const filename = "data.csv"; let data = '\"' + this.keys.join('\",\"') + '\"\r\n'; for (const record of this.records){ if ( this.checkCondition(record) ){ data += '\"' + record.join('\",\"') + '\"\r\n'; } } const bom = new Uint8Array([0xef, 0xbb, 0xbf]); const blob = new Blob([bom, data], { type: "text/csv" }); const url = (window.URL || window.webkitURL).createObjectURL(blob); const download = document.createElement("a"); download.href = url; download.download = filename; download.click(); (window.URL || window.webkitURL).revokeObjectURL(url); }, // フォームタイプをチェックする isHidden: function(key){ return /^.*:hidden/.test(key) }, isSelect: function(key){ return /^.*:select\[.*\]$/.test(key) }, isRadio: function(key){ return /^.*:radio\[.*\]$/.test(key) }, isCheckbox: function(key){ return /^.*:checkbox\[.*\]$/.test(key) }, // シートの項目名末尾に付与した選択肢の配列を返す getOptions: function(key){ const param = /:(select|radio|checkbox)\[.*\]$/.exec(key) // param[0] => ':select["A","B","C"]' const optionsString = /\[.*\]/.exec(param[0]) // optionsString[0] => '["A","B","C"]' return JSON.parse(optionsString[0]) // return => ["A","B","C"] } } }) </script> </body> </html>

補足情報(FW/ツールのバージョンなど)

全くの素人のため、専門用語等はほとんどわかりません。
見よう見まねで色々引っ張ってきて使用している状況です。

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問