Замените значение времени в программном коде, используя Excel VBA или Javascript - PullRequest
0 голосов
/ 07 октября 2018

Я пытаюсь сделать прокрутку текста караоке песни.Лирическое программное обеспечение выводит код, который содержит время в секундах, которое мне нужно конвертировать.

У меня есть две версии одной и той же песни.Один работает со скоростью 52 ударов в минуту (ударов в минуту), что является более медленной версией, а другой - со скоростью 104 ударов в минуту, что является более быстрой версией.

Я закончил первую версию, которая заняла у него много времени.Я хочу преобразовать код таким образом, чтобы я мог получить более быструю версию автоматически.

Вот пример кода

<item dStartTime="4" dEndTime="8" n3DRhythm="2" str3DSceneLayoutFile="">    
    <text>Batti Gul Meter Chalu</text>
</item> 
<item dStartTime="9.52" dEndTime="14.47" n3DRhythm="2" str3DSceneLayoutFile=""> 
    <text>rajj&lt;10.44&gt; ke&lt;10.99&gt; rulaya</text>
</item> 
<item dStartTime="14.47" dEndTime="19.06" n3DRhythm="2" str3DSceneLayoutFile="">    
    <text>rajj ke&lt;15.94&gt; hansaya</text>
</item> 

Я хочу преобразовать тот же код, как показано ниже, где время в секундах должно быть ровно наполовину с двумя десятичными точками

<item dStartTime="2" dEndTime="4" n3DRhythm="2" str3DSceneLayoutFile="">    
    <text>Batti Gul Meter Chalu</text>
</item> 
<item dStartTime="4.76" dEndTime="7.24" n3DRhythm="2" str3DSceneLayoutFile="">  
    <text>rajj&lt;5.22&gt; ke&lt;5.50&gt; rulaya</text>
</item> 
<item dStartTime="7.24" dEndTime="9.53" n3DRhythm="2" str3DSceneLayoutFile="">  
    <text>rajj ke&lt;7.97&gt; hansaya</text>
</item> 

Я взял код в MS Excel и попытался использовать подстановочные, объединенные и другие несколько формул для достижения того, что мне нужно, но я не могу этого сделать, и хотя Excel vba может помочь, но я не могу сделать это в vba.Прошу вас, ребята, помочь мне в этом, так как мне нужно конвертировать много песен.Ваша помощь поможет сэкономить много времени.Любая помощь в Excel VBA, JavaScript или любой другой способ заменить код.

В разделе <item> мне нужно преобразовать dStartTime и dEndTime

В <text> раздел, мне нужно преобразовать все, что выглядит как число

Спасибо

Ответы [ 2 ]

0 голосов
/ 07 октября 2018

При этом используется синтаксический анализатор DOM для записи значений и продолжительности после чтения каждого раздела HTML из HTML-файла.Я боролся с доступом к узлам текста, поэтому мне пришлось взломать то, что меня не устраивает.Это означает, что вы знаете искомое значение, что означает, что вы можете выполнить замену строки html с помощью метода regex .Replace.Для dStartTime и dendTime вы можете выполнить прямую замену внешнего HTML.Это заменит только в текущем HTMLDocument, если вы не записываете обратно в файл.SetAttribute не работает в этом случае.Я не уверен, почему я не смог получить доступ к текстовым узлам, особенно из-за отсутствия исходного HTMLDocument.Было бы хорошо, если бы кто-то мог решить это.

item.outerHTML = Replace$(item.outerHTML, "dstarttime=" & Chr$(34) & item.dstarttime & Chr$(34), "dstarttime=" & 666 & Chr$(34)) 'example  666 as replace value. 

vba:

Option Explicit
Public Sub GetValues()
    'VBE > Tools > References > HTML Object Library
    Dim html As HTMLDocument
    Debug.Print "doc1", vbNewLine
    Set html = GetHTMLFileContent("C:\Users\User\Desktop\test.html") 'first html document. Info saved in text file with .html extension
    GetItems html
    Debug.Print "doc2", vbNewLine
    Set html = GetHTMLFileContent("C:\Users\User\Desktop\test2.html") 'second html document. Info saved in text file with .html extension
    GetItems html
End Sub
Public Sub GetItems(ByVal html As HTMLDocument)
    Dim items As Object, item As Object, counter As Long
    Set items = html.getElementsByTagName("item")
    For Each item In items
        Debug.Print " item " & counter + 1
        Dim itemArr() As String
        itemArr = Split(html.body.innerHTML, "</ITEM")
        Debug.Print "startTime = " & Round(item.dStartTime, 2), "endTime = " & Round(item.dendTime, 2), "duration : " & Round(item.dendTime - item.dStartTime, 2)
        Debug.Print "Associated text numbers "
        On Error Resume Next
        GetTextAttributeNumbers Split(itemArr(counter), "<TEXT>")(1)
        On Error GoTo 0
        counter = counter + 1
    Next item
End Sub


Public Sub GetTextAttributeNumbers(ByVal inputString As String)
    Dim matches As Object, iMatch As Object

    With CreateObject("vbscript.regexp")
        .Global = True
        .MultiLine = True
        .IgnoreCase = True
        .Pattern = "\d{1,}(\.\d+)?"
        If .TEST(inputString) Then
            Set matches = .Execute(inputString)
            For Each iMatch In matches
                Debug.Print iMatch

            Next iMatch
        End If
    End With
End Sub

Public Function GetHTMLFileContent(ByVal filePath As String) As HTMLDocument
    '"C:\Users\HarrisQ\Desktop\test.html"
    Dim fso As Object, hFile As Object, hString As String, html As New HTMLDocument
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set hFile = fso.OpenTextFile(filePath)

    Do Until hFile.AtEndOfStream
        hString = hFile.ReadAll()
    Loop

    html.body.innerHTML = hString
    Set GetHTMLFileContent = html
End Function

Для правильного разбора документов требуется следующий синтаксис:

Doc1

<html>
 <head></head>
 <body>
  <item dstarttime="4" dendtime="8" n3drhythm="2" str3dscenelayoutfile=""> 
   <text>
    Batti Gul Meter Chalu
   </text> 
  </item> 
  <item dstarttime="9.52" dendtime="14.47" n3drhythm="2" str3dscenelayoutfile=""> 
   <text>
    rajj&lt;10.44&gt; ke&lt;10.99&gt; rulaya
   </text> 
  </item> 
  <item dstarttime="14.47" dendtime="19.06" n3drhythm="2" str3dscenelayoutfile=""> 
   <text>
    rajj ke&lt;15.94&gt; hansaya
   </text> 
  </item> 
 </body>
</html>

Doc2

<html>
 <head></head>
 <body>
  <item dstarttime="2" dendtime="4" n3drhythm="2" str3dscenelayoutfile=""> 
   <text>
    Batti Gul Meter Chalu
   </text> 
  </item> 
  <item dstarttime="4.76" dendtime="7.24" n3drhythm="2" str3dscenelayoutfile=""> 
   <text>
    rajj&lt;5.22&gt; ke&lt;5.50&gt; rulaya
   </text> 
  </item> 
  <item dstarttime="7.24" dendtime="9.53" n3drhythm="2" str3dscenelayoutfile=""> 
   <text>
    rajj ke&lt;7.97&gt; hansaya
   </text> 
  </item> 
 </body>
</html>

Это означает, что, если его нет, добавить в ряд отсутствующие начальную и конечную строки.

"<html><head></head><body>" &  yourHTMLString & "</body>
</html>"

Пример выводаиз второго документа:

enter image description here

0 голосов
/ 07 октября 2018

В Javascript вы можете использовать DOMParser для преобразования строки в документ, после чего вы можете перебирать каждый <item>, изменять атрибуты dStartTime и dEndTime, а затем изменять любые числа в дочернем элементе.<text> узел:

const str = `<item dStartTime="4" dEndTime="8" n3DRhythm="2" str3DSceneLayoutFile="">    
    <text>Batti Gul Meter Chalu</text>
</item> 
<item dStartTime="9.52" dEndTime="14.47" n3DRhythm="2" str3DSceneLayoutFile=""> 
    <text>rajj&lt;10.44&gt; ke&lt;10.99&gt; rulaya</text>
</item> 
<item dStartTime="14.47" dEndTime="19.06" n3DRhythm="2" str3DSceneLayoutFile="">    
    <text>rajj ke&lt;15.94&gt; hansaya</text>
</item> `;

const doc = new DOMParser().parseFromString(str, 'text/html');
const halve = num => Math.round(100 * num / 2) / 100;
const halveAttrib = (node, name) => {
  const newVal = halve(node.getAttribute(name))
  node.setAttribute(name, newVal);
};

doc.querySelectorAll('item').forEach((item) => {
  halveAttrib(item, 'dStartTime');
  halveAttrib(item, 'dEndTime');
  item.children[0].textContent = item.children[0].textContent
    .replace(/\d+(\.\d+)/g, num => halve(num).toFixed(2));
});

const output = doc.body.innerHTML
  .replace(/dstarttime/g, 'dStartTime')
  .replace(/dendtime/g, 'dEndTime')
  .replace(/n3drhythm/g, 'n3DRhythm')
  .replace(/str3dscenelayoutfile/g, 'str3DSceneLayoutFile');
console.log(output);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...