インストールレスプログラミング( ´ー`)

VBA , JavaScript , HTAなど 365アプリはインストール必要ですが、仕事に無いケースはほぼないから(・_・;)

ツイッターで備忘録は難しかった。

ずいぶん久々になりますが、まだアカウントの内容覚えていたのでここにいろいろメモをします。

自分自身忘れたときは、見には来ていたので、役には立った。

タイトルを変えてみました。

教育界でもPythonがちやほやされていますし、覚えた方がいいのかな・・という気持ちはあるにはあります。

本も数冊買って、買うかどうかの選択のために簡単に目を通しただけで、その後進みはしません。

ですが、前から変わらないことはある。

職場ではインストールが必要な言語は使えないのです。ちなみにPowerShellとかもセキュリティのためなのか、使わせてもらえません。

私に許される言語環境はあいかわらず、VBA,Javascriptを使ってHTMLで書くか、HTAにするかくらい。

数年たった今もそれは変わらず、むしろきびしくなったかも。

インストール不要、これが一番必要な性能であったりします。

あと、Microsoft Officeと呼んでいたアプリケーション群はみるみる進化をしています。わたしにとっては、基本はそれらにがっつり助けられてそれを補助できるのが一番の手段です。

なので、今もVBA愛好家であることを自負しています。プロのプログラマーじゃないし、VBAはどうのこうのっていうのは関係ないヽ(´ー`)ノ

なんか、EXCELとかいつからかわからないけど自動化って機能あって、その中身ってがっつりJavascript系ですよね。。

インストール前提はプロにまかせればいい( ´ー`)

自分が日々の職務で助けられている各種知識を自分に必要な形で残していくというのを、久々にしてみようと思っています。

まず、しなきゃいけないことをメモ。

・InternetExplorerが任期を終え、EdgeやChromeを制御する。

これは一昨日あたりから急速に解決を見せ始めています。
qiita.com
こちらです。神ですよ。もうどれだけ感謝してもしきれないレベル。

ただ、汎用的であるので、このまま使用すると遅いという点があります。

ログもきっちり出ているので、それが速度を制限しているんですが、そのあたりは調整しよう。

ただ、HTMLオブジェクトに関する機能をうまく使えば、劇的に効率は上がりそうなので、先は明るい。。( ´ー`)

OpenCVによるパターンマッチング

これもIEが任期を終えるときにどうにかしたい、というのとOneNoteを私結構仕事で使用しているので、それを自動化するためにです。

UWSCはインストールが不要なため、実は職場では使えるんですが、セキュリティ的に使うべきではないという判断から、その代わりを求めていました。

Pythonとは仲がいいようなんですけどね。。何度も言うけど使えないのです。
  
vbaexcel.slavesystems.com
  
こちらが私が見つけた中で一番助けられたもので、一応動くところまでいきました。

結局dllを望むとおりに作るところは、理解が及びませんでしたが、dllを載せてくださってるので、それを利用させてもらうとうまく動く。

また本腰入れて取り組めるときにがんばろうとは思っていますが、2023現在でわたしにわかりやすく誰かまとめてくれないだろうか、とたまに検索はしています。

制御できないものはsendkeyとパターンマッチングができればなんとかできそうだと思われる。

・365のExcelの関数群

すごいですね。VBAにこだわらず、プログラミングにはなりませんが、関数も備忘録を残していきたい。

昨日まで、条件付き書式の数式によるやり方を誤解しているのを発見し、とても恥ずかしかったですが、おかげで、かなりスムーズにできるようになった。

・Wordのスタイルについて

去年あたりから学びました。だいたい細かく制御できるようになったので、これもまた以前より仕事効率は格段に上がりました。なかなか癖が強いので試行錯誤を残したいところ。



とにかくなんでもすぐ忘れるので、書きとめないとだめですし、いつでも見れるのはやっぱりWebかなと思うので、久々に残していきたいと考えております。

書くと学ぶ意欲が上がるので、そういう意味もありますね。

自己書き込み型再び HTAネタ

以前失敗した自己書き込み型の掲示板ぽいやつです。

強引に解決?したものをメモで。

前回のものはローカルで使う場合は動くけどネットワーク上で動かすとADODB.Streamが警告を受けて止まってしまうというもの。

FilesystemObjectを使う限り,UTF-8は使えないからとしばらく前にあきらめていました。

でも,ある本で,JavascriptShift_JISで組んでいるところを発見。meta文で指定すれば普通に使えるそうです。

それなら・・と作り直してみました。ちなみにShift_JISだと環境依存文字で結構致命的なことになるので,推奨されないUTF-16でやってみることにしました。

<!doctype html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" charset="utf-16"> 
<title>Write Me</title>
<style type="text/css">
    *{font-family:"メイリオ",sans-serif;font-size:calc(18px+1vw);}
    #log{font-size: 5vmin;background-color: lightcyan}
    #input{width:80vw;font-size: 5vmin;background-color:cornsilk}
</style>
</head>
<body>
<div id="targetDiv"></div>
<div id="log"></div>
<script>
    var targetDiv=document.getElementById("targetDiv")
    var DataCount,ForReading = 1,ForWriting=2,ForAppending = 8
    var User= new ActiveXObject("WScript.Network").UserName;
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var fileName=location.pathname.split("\\").pop()
    targetDiv.innerHTML="<form name='form'>"+
        "<input type='text' id='input' name='text' onFocus='func()'>"+
        "<input type='text' name='dummy' style='display:none'>"+
        "<input type='button' href='#' value='送信' onclick='writeMe()' style='font-size:5vmin'></form>"
    const timerID=setTimeout(func2,1000)
    var inputbox=document.getElementById("input")
    inputbox.addEventListener('keydown',onkeydown)
    //end of root
    function func(){clearTimeout(timerID)}
    function func2(){location.reload()}
    function onkeydown(e){
        if (e.keyCode=='13'){writeMe()}
    }
    function writeMe(){
        var res=document.form.text.value
        var ForReading = 1,ForWriting = 8,ForAppending = 2
        var data = fso.OpenTextFile(fileName, ForReading, false,-1)
        var srcdata = data.ReadAll()
        data.Close()
        var srcArr=srcdata.split("\r\n")
        var lineCount=srcArr.length
        
        for (var i=lineCount-1;i!=-1;i--) {
            if (srcArr[i].indexOf("★☆★□■データ書き込みこの下■□★☆★")>0){
                var データ開始行=i
                break
            }
        }
        srcArr.splice(i+1,0,User+","+res)
        var data2 = fso.OpenTextFile(fileName, ForAppending, true,-1)
        data2.Write(srcArr.join("\r\n"))
        data2.Close()
        location.reload()
    }
</script>
<p id='data' hidden flg='★☆★□■データ書き込みこの下■□★☆★'>
</p>
<script>
    var logdiv=document.getElementById("log")
    var logdata=document.getElementById("data").innerHTML
    logdata=logdata.split("\n")
    var htm=""
    for (var i=0;i<logdata.length;i++){
        if (logdata[i].split(",")[1]!=undefined) htm=htm+logdata[i].split(",")[1]+"<br>"
    }
    if(logdata=="") {logdiv.innerHTML=""}else{logdiv.innerHTML=htm}
</script>
</body>
</html>

けっこう短いですが,これで全部。メモ帳などに貼り,拡張子HTAUnicodeで保存します。
f:id:chemiphys:20190604211616p:plain
文字コードを間違ってなければたぶん動きます。データは

<p id='data' hidden flg='★☆★□■データ書き込みこの下■□★☆★'>
</p>

この間にどんどん入っていくはずです。

単独ファイルで動く掲示板というものを実現できた気がします。

サーバー内の散逸するファイルへのリンク集とか作るのに面白いですね。

自動更新を数秒ごとにするので,複数人で開いても普通にチャットっぽくなる。

コードも短くお手軽なので,使い道は考えていませんがお気に入りのコードでした。

Javascript  SVGのツールチップを表示する

さんざん悩んでいたものが解消したので,備忘録

SVGで図形の上に来た時に任意の値を表示したいというもの。
titleとかを使えば似たようなものはできたりしますし,svgの直後に文字をつけてCSSでなんとかする手もありました。でも制約がけっこうあり,不満でした。
やっと満足ができるものになったので載せます。

SVGの図形部分もJavaScriptで書けるわけですが,そこは情報がかなり豊富なのでいいとして,ツールチップのとこが今回の本題です。

<!DOCTYPE html>
<html lang="jp">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style type="text/css">
        #label {
            padding: 3px;
            background-color: beige;
            position: absolute;
        }
    </style>
</head>

<body>
    <div id="label"></div>
    <svg width="400" height="200">
        <rect id="a" x="10" y="10" width="80" height="80" fill="yellow" onclick="Name()"
        onmouseover="call()" onmousemove="point()" onmouseout="hidelabel()" data-label="aa"></rect>
        <rect id="b" x="100" y="10" width="80" height="80" fill="pink" onclick="Name()"
        onmouseover="call()" onmousemove="point()" onmouseout="hidelabel()" data-label="bb"></rect>
        <rect id="c" x="300" y="10" width="80" height="80" fill="blue" onclick="Name()"
         onmouseover="call()" onmousemove="point()" onmouseout="hidelabel()" data-label="箱だよ"></rect>
    </svg>
    <script>
        var labeldiv = document.getElementById("label")
        function Name() {
            alert(event.target.getAttribute("id"))
        }

        function point() {
            X = event.x + document.body.scrollLeft
            Y = event.y + document.body.scrollTop
            labeldiv.style.left = X + 10 + "px"
            labeldiv.style.top = Y + "px"
        }

        function call() {
            labeldiv.style.display = "block"
            labeldiv.innerText = event.target.getAttribute("data-label")
        }

        function hidelabel() {
            labeldiv.style.display = "none"
        }
    </script>
</body>

</html>

説明です。
labelというidのdivがツールチップの本体となります。absolute指定しているので,自由に配置できます。
書式はcss部分で自由に変更可能。
図形の上にマウスカーソルが行ったとき onmouseoverに指定している関数が呼び出されます。各四角のdata-label属性を読み取ってlabelの文字列を書き換えます。

図形上を動いているときはonmousemoveに指定している関数が呼び出されます。
マウス位置を読み取ってそれでlabelのdivの座標を修正しています。定位置にするなら図形の座標を読み取ってうまく指定すればいいかな。

そして図形から離れるときはonmouseoutが呼び出されてdivを非表示にします。

とてもシンプルに書けてスムーズに動いてくれる。

これはhtaとして保存してもちゃんと動きます。htaで試す方はメモ帳にはりつけて UTF-8で保存しましょう。

グラフの各パーツの説明をこのやり方でやるようになり,満足がいくところに来ました。

javascriptすげーの日々はまだ続いています。htaにもそのまま使えるのでほんと助かる。。

HTA 自己書き込み型のスクリプト(失敗)

すっかりHTAにしか興味がないので,ここに書くのも憚られるんですが,自分用メモとしてなら名前詐欺もいいかなと思いそのまま書きます。
HTAネタです。

やったことは,自己書き込み型のスクリプト
テキストボックスを一個もっていて,そこに打ち込んだものが自分自身に書き込まれるというもの。

条件によっては成功と言えるものができました。まずスクリプトを載せます。
vscodeの自動整形で検索部分がずれてて動かなくなってたので訂正しました。(-_-;)

<!doctype html>
<html>

<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" charset="utf-8">
    <title>Write Me</title>
    <style type="text/css">
        #log {}
    </style>
</head>

<body>
    <div id="targetDiv"></div>
    <div id="log"></div>
    <script>
        var targetDiv = document.getElementById("targetDiv")
        var DataCount, ForReading = 1, ForWriting = 2, ForAppending = 8
        var User = new ActiveXObject("WScript.Network").UserName;
        var fso = new ActiveXObject("Scripting.FileSystemObject");
        var fileName = location.pathname.slice(1)
        targetDiv.innerHTML = "<form name='form'>" +
            "<input type='text' name='text' maxlength='30' onFocus='func()'>" +
            "<input type='button' href='#' value='送信' onclick='writeMe()'></form>"
        const timerID = setTimeout(func2, 3000)
        //end of
        function func() { clearTimeout(timerID) }
        function func2() { location.reload() }
        function writeMe() {
            var res = document.form.text.value
            //定数宣言
            var adTypeText = 2
            var overWrite = 2
            var oldData = ""
            var ado = new ActiveXObject("ADODB.Stream")
            ado.Type = adTypeText
            ado.Charset = "utf-8"
            ado.Open()
            ado.LoadFromFile(fileName)
            var ado2 = new ActiveXObject("ADODB.Stream")
            ado2.Type = adTypeText
            ado2.Charset = "utf-8"
            ado2.Open()
            var line = ""
            while (!ado.EOS) {
                line = ado.ReadText(-2)
                if (line == "    <p id='data' hidden>") {
                    ado2.WriteText(line, 1)
                    ado2.WriteText(User + "," + res + "," + Date() + "<br>", 1)
                } else {
                    ado2.WriteText(line, 1)
                }
            }
            ado.Close()
            ado2.SaveToFile(fileName, overWrite)
            ado2.Close()
            location.reload()
        }
    </script>
    <p id='data' hidden>
    </p>
    <script>
        var logdiv = document.getElementById("log")
        var logdata = document.getElementById("data").innerText
        logdata = logdata.split("\n")
        var htm = ""
        for (var i = 0; i < logdata.length; i++) {
            htm = htm + logdata[i].split(",")[1] + "<br>"
        }
        if (logdata == "") { logdiv.innerHTML = "" } else { logdiv.innerHTML = htm }
    </script>
</body>

</html>

メモ帳にでも張り付けて,UTF-8形式で保存,拡張子をHTAにすればたぶん動くものです。

テキストボックスが一つだけあり,そこに打ち込んで送信を押すと,すぐ下にログがでてきます。エンター対策はしていません。

同じパソコン上でいくつも同時起動してやってみると,面白い感じです。3秒ごとに自動更新しているので,それなりに同期されると思います。

そう,自分の環境では動くんです。

失敗の部分は,ネットワーク上のフォルダに入れたときに動かないってこと。致命的な部分です。

エラーメッセージを家では確認できないんですが,少し調べたところ,ADODB.Streamは,InternetExplorerと同じレベルのセキュリティ制限を受けるようで,書き込みを阻害されます。

なので,自分のデスクトップとかでは普通に動くけど,ネットワーク上の場所に置くと使えない。

私には意味がないものになってしまいました。(;´∀`)

でも,自分自身を書き換えるというのはやってて面白かったので,とりあえず載せます。データは

<p id='data' hidden>
    </p>

の間にどんどん書き込まれていくことになっています。

救いなのは,FileSystemObjectのほうは,同様の制限を受けないこと。なので,外部テキストファイルを作っての掲示板は十分動くようでした。

FileSystemObjectがUTF-8の書き込みができるなら,わたしの望みは果たせたのですが,それはできません。なので,FileSystemObjectで同じ処理をすると,がっつり文字化けしてどうにもならない。

同じことで悩まないように,失敗例としての記事でした。

それにしてもHTAは面白く,VBAで仕事もしているんですが,そちらには最低限しか興味が行っていません。

Javascriptがすごい。CSSがすごい。 HTML5がすごい。 なので,それらを扱えるHTAはものすごい(;´∀`)

EdgeがChromium版を出してきましたね。実際私はそれを使っているんですが,これが主流になってきたら,もし望む方向に進めばさらにHTAはすごくなる・・かも。

そんな甘いことはないだろうなぁとは思いつつ,やっていくんですが,現状だけでも十分HTAの恩恵は受けています。

HTA自身が使えなくなっても Javascript,CSS,HTMLが書ければWebアプリでも生きていけますし,無駄にはならない・・はずかな。

音声ファイルデータを後につけて実行するメモ

自分用メモ

音声データをBase64でテキスト化して,最後に付け足して使うことが可能だったこと。

<!doctype html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE11=edge" charset="utf-8">
<title>テスト中</title>
<script>
    window.onload=function(){
    mus.play()
    new Vue({
        el:"#app",
        data:{
            myText:"今日はいい天気です。"
        }
    })
    
    }
</script>
    </head>

<body>
<div id="app">
    <textarea v-model="myText"></textarea>
    <p>文章は,「{{ myText }}」</p>
    <p>文字数は{{myText.length}}文字です。</p>
</div>
</body>
</html>

<script>
    var mus=Audio()
    mus.src="data:audio/mp3;base64,//uQZAAAA31jQQZSQAI3LFhAwRQATV1VJBz0AADZgCODhjAA8CRkDJjfFWDi3g  ~音声の長いテキストデータ~ "
</script>
<script>
    /*! * Vue.js v2.5.22   * (c) 2014-2019 Evan You   * Released under the MIT License.   */
    !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof de  ・・・
</script>

音声や画像のSVGデータ,またはJQueryやVue.jsなどのライブラリをHTML内に全部放り込めば,

他ファイル依存がなくなって,作ってかなーり経ったHTAファイルでもファイル依存から解放されるんじゃないかということを試しています。

無知だからいろんなことを試行錯誤するしかない。

音声についてはとりあえずちゃんと動いた。

これであまり長い音声を使わない前提でなら,音声ファイルをどこどこに忘れずに入れておいてとかいうことから解放される。

画像データもAdobeのソフト群にお世話になっている自分としてはSVGでだいたい事足りそう。

データ部分はできれば最後に付け足しておいて,読み返さないといけないコード部分は上に固まってほしい派です。

あと,ライブラリもあまりにも長いものでなければつけてしまえそう。こちらは個人使用の段階ではある程度好き勝手でいいと思うんですが,

他人に紹介しようとしたものができた場合微妙でもあります。

ただ,依存する外部ファイルを極力消したいと思う場合たぶん私は避けないと思う。

テキストで数百キロバイトというのはコードで見るとすごいけど,データサイズとしては小さいですしね。

上記のHTMLの中には音声データとVue.jsを入れてみるということをしました。ライブラリも音声もとても長いのでぶちっと切ってますからもちろん上のコードそのままでは動きませんが,

数十キロバイトのライブラリや画像データなら最後に内部に放り込んでおけば一つのファイルでいいものができそうな気がします。

外部ファイルとする方が使いまわし等で適正なんでしょうけど,

私を含めて,あまり深くその言語を知らない場合,しばらくして忘れてしまうと前提となるファイルとの位置関係が変わってしまったり,絶対参照しているファイルが年度を超えていくうちに

なくなってしまったりということは往々にしてあります。

なので,その方法の是非は抜きにして,一つのファイルで納めてしまいたいという強い希望がいつも頭にあるので,無駄なこととはいえできることを試した。

これでかなりストレスが減るなぁ。

本収集以上にはあまり進んではいませんが,自分がしたいことはSPAと呼ばれるやつのようで,Vue.jsととても相性が良いようです。

JQueryで作られたものもよく出会うため,JQueryの本とかも可能な限りたくさん集めました。

プレーンなJavascriptももちろんたくさん。

本にまみれてますが,なんとなく方向性ができつつあるので,来年度はけっこう楽しみ。

ただコードの中にライブラリを内包する場合,ライブラリによくあるMITライセンスというのとの上手な付き合い方はどうなるのか,調べないとなぁと思っているところです。

mp3ファイルをbase64でテキストにしてjavascriptで活用する

すっかりHTAにはまりこんで,Powerpointに戻る気配がありません(;´∀`)

JavascriptCSS,HTML5でできることの幅広さにおののく毎日で,日々本がたまりにたまって読める気配がない。

でも,気の向くままに,調べものするときに読むことで,少しずつ,少しずつ頭の中に概念みたいなものができつつある気がします。

読みながらやれば大概なんとかなりそうな感じです。

さて,HTAの数少ない不満は 画像や音声ファイルを別ファイルで用意しないといけない,という不満でした。

依存ファイルがあると,作って時間がたつと忘れてしまうし,もし誰かに欲しいといわれたときに提供したとして,前提条件が崩れるとうまく動かなくなるのは容易に予測できる。

jQueryやグラフのライブラリはいくらかあきらめがつきますし,私が使う棒グラフ・円グラフくらいならSVGCanvasでどうにかすればいい話だよなぁとも思う。

Illustratorもあるので,画像データはけっこうSVGにできますし,CSSがやれることも半端ない。

画像面ではほぼ問題は見当たりません。

でも,音源ファイルがどうにかならないのかなーと調べていたら,Base64エンコードすることで解決しそうでした。

こちらの記事のおかげです。

qiita.com

そこで,mp3ファイルをWindowsのcertutilコマンドでエンコードするものをexcelvbaで組んでみました。

フォルダを指定して,その直下のmp3ファイルをエンコードします。

そして,さらにそれにちょっとhtmlを足して,htmファイルにして音を確認する感じに作ってみました。

完全に自分用(ノ´∀`*)

前者がこんな感じ

Sub base64encode()
    Dim strPathName As String
    
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then
            strPathName = .SelectedItems(1)
        End If
    End With
    
    If strPathName = "" Then Exit Sub
    
    Dim strFileName As String
    
    strFileName = Dir(strPathName & "\*.mp3", vbNormal)
    If strFileName = "" Then Exit Sub
    Do While strFileName <> ""
        DoEvents
        Shell "certutil -f -encode " & strPathName & "\" & strFileName & " " & strPathName & "\" & Left(strFileName, InStr(strFileName, ".mp3") - 1) & ".htm"
        strFileName = Dir()
    Loop
End Sub

とても短いです(;´∀`)でもこれでhtmファイルを吐き出します。
ただこのままではどんな音だったか確認もできないので,それにちょっと編集をするのが次のコード

Sub edittext()
    Dim strPathName As String
    
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then
            strPathName = .SelectedItems(1)
        End If
    End With
    
    If strPathName = "" Then Exit Sub
    
    Dim strFileName As String

    strFileName = Dir(strPathName & "\*.htm", vbNormal)
    Dim inputText, outputText, records, lineStr, flg As Boolean
    
    
    Do While strFileName <> ""
        DoEvents
        Set inputText = CreateObject("ADODB.Stream")
        With inputText
            .Charset = "UTF-8"
            .Mode = 3 '読み書き
            .Type = 2 'テキスト
            .Open
            .LoadFromFile strPathName & "\" & strFileName
        End With
        
        Set outputText = CreateObject("ADODB.Stream")
        With outputText
            .Charset = "UTF-8"
            .Mode = 3 '読み書き
            .Type = 2 'テキスト
            .Open
            .writetext "<audio controls='controls' autoplay style='border:3px solid red;'><source src='data:audio/mp3;base64,", 1
            flg = True
            Do Until inputText.eos
                DoEvents
                lineStr = inputText.readtext(-2)
                If flg = True Then
                    flg = False
                Else
                    .writetext Replace(lineStr, vbCrLf, ""), 0 '問題あったら1
                End If
            Loop
            .writetext "", 1
            .writetext "' type='audio/mp3' /></audio>", 0
            .savetofile strPathName & "\" & strFileName, 2
            .Close
        End With
        strFileName = Dir()
    Loop
End Sub

この二つをつなげるとうまくいかなかったので,タイミングを分ける意味で分割しています。
さっきのコードで吐き出したhtmファイルにaudioタグを付け加えることで,

そのhtmを開くと音を鳴らすようにしただけです。

あと,base64で吐き出したものを一行にするように少し細工をしています。

これで一応文字列にはなりました。

今度はjavascriptでうまく使えるように調整をしていこう。

<meta http-equiv="X-UA-Compatible" content="IE=edge" charset="utf-8">

この一文を頭に付け加えるだけで,htaにしてもきちんと動くようです。

htaの制限ってあんまりないのかな・・と最近思います。

このブログの名前の変更を検討するべきなんだろうか・・(;´∀`)

HTA Audioオブジェクト meta記述で使えた

昨日までの成果でHTAを作る場合にmeta記述でEdge互換にするといろいろ使えたってのを書いていました。

以前失敗したAudioオブジェクトのやつがふいに頭によぎり試してみた。

ためしてみた

まず前の失敗例

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
  var pu=Audio()
  pu.src="end.mp3"
  pu.play()
</script>
</head>

<body>
</body>
</html>

f:id:chemiphys:20190115100424p:plain
この画面が出て使えない。レガシーブラウザモード? (IE6くらいの時代の互換らしい)

metaだけ変えた 他はいじらず

<!doctype html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" charset="utf-8">
<title></title>
<script>
  var pu=Audio()
  pu.src="end.mp3"
  pu.play()
</script>
</head>

<body>
</body>
</html>

音なりますよ! エラーも出ません!

これは大きい。

夢が広がりますね。

Libralyへの苦手意識が減ったので,JQueryの学習も始めました。JavaScriptへの理解が進んだ後でもありますし,意味もあるかな。