Excel VBA управляет веб-страницей с нокаутом; кажется, работает; но ничего не сохраняется

резюме:

в основном пытается редактировать веб-сайт с помощью Excel VBA. Изменения, похоже, работают, но когда я использую кнопку Сохранить, ничего не сохраняется. Я знаю, что кнопка save работает, объяснено ниже. Так почему же мои обновленные данные, которые видны на экране, не сохраняются?

история:

у меня есть этот код, над которым я работал некоторое время с Excel VBA. Он открывает веб-страницу в internet explorer, перемещается там, где я хочу, заполняет кучу данных, все которые появляются на экране, используя различные методы, такие как:

For Each objElement In objElementColl
ExtractedName = objElement.outerHTML

If InStr(ExtractedName, "NewPermit") > 0 Then
objElement.Checked = True

и

Set DropDown = objHTML.getElementById("ProjectFile-AccreditedCertifierId")
DropDown.selectedIndex = 1

или

objHTML.getElementsByName(ElementName)(0).Value = ValueCheck

все из которых работают очень хорошо, и изменения на экране. Затем я нажимаю save с помощью:

Set objElementColl = objHTML.getElementsByClassName("btn")

For Each objElement In objElementColl
    ExtractedName = objElement.outerHTML

    If InStr(ExtractedName, "click: save, enable:") > 0 Then
        objElement.Click
        ExtractedName = 1
        Exit For
    End If
Next

который снова работает нормально. Проблема в том, что он фактически не сохраняет мои изменения из кода из 3pieces выше. Что я пробовал-это

A) приостановите мой код и вручную нажмите save (та же проблема)

b) приостановить мой код, вручную измените флажок и запустите код для сохранения (сохраняет ручное изменение, но не закодированные

c) приостановить код и вручную изменить поле и вручную сохранить (сохраняется только вручную измененное поле)

Итак, сверху кажется, что мой щелчок сохранения работает, но по какой-то причине, хотя поля заметно изменены и заполнены с помощью кода, существует разрыв между видимым и фоном.

в любом случае, некоторый исходный код HTML. Что chrome показывает мне при проверке элемента, который я меняю:

    <fieldset>
        <legend>Proposal</legend>

        <div class="col-xs-12 col-sm-8 col-md-6">
            <div class="row">
                <div class="col-xs-2 form-group">
                    <label for="ProjectFile_ProposalLot">Lot</label><input class="form-control" data-bind="textInput: ProjectFile().ProposalLot" maxlength="100" name="ProjectFile-ProposalLot" type="text" />
                </div>
                    <div class="col-xs-2 form-group" data-bind="visible: ProjectFile().StateId() != 7 && ProjectFile().StateId() != 5">
                        <label data-bind="text: ProjectFile().ProposalDpLabel()"></label>
                        <input class="form-control" data-bind="textInput: ProjectFile().ProposalDp" maxlength="100" name="ProjectFile-ProposalDp" type="text" />
                        </div>

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

var ProjectFileEditViewModel=(function(){__extends(ProjectFileEditViewModel,ViewModel.Model);function ProjectFileEditViewModel(){ProjectFileEditViewModel.__super__.constructor.apply(this,arguments);};ProjectFileEditViewModel.prototype.fields=function(){return {"Id":new ViewModel.NumberField(0),"StateId":new ViewModel.NumberField(0),"DefaultOfficeAddressId":new ViewModel.ObservableField(),"Name":new ViewModel.ObservableField(),"ExistingApprovalDate":new ViewModel.DateField("DD/MM/YYYY"),"ProjectClosed":new ViewModel.ObservableField(),"ProposalAddress":new ViewModel.ObservableChildField(exports.AddressViewModel,this),"Zoning":new ViewModel.ObservableField(),"ProposalLot":new return ProjectFileEditViewModel;})();if(exports.ProjectFileEditViewModel==null)exports.ProjectFileEditViewModel=ProjectFileEditViewModel;

есть и такое... опять гораздо дольше:

Buildaform.model=new Buildaform.ProjectPageViewModel({ ... ,"ProposalLot":null .... }

Я думаю, что это последнее имеет какое-то отношение к этому, и я не знаю, Могу ли я это изменить.

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

2 ответов


на ваш комментарий что:

b) приостановите мой код, вручную установите флажок и запустите код для сохранения (сохраняет ручное изменение, но не закодированные

Кажется, что проблема заключается в элементах управления формой настройки кода, а не в том, что код нажимает кнопку Сохранить.

Это, кажется, проблема не связана с VBA но с поведением офф - см. это так пост. Уместным комментарием является:

ваша проблема в том, что ko подписывается на событие click внутри проверенной привязки:

у спрашивающего в этом посте есть аналогичная проблема с вами-они пытаются Регистрация флажок (для изменения представления), но он не обновляет ни viewmodel, ни саму базовую модель. Нокаут-это MVVM основы.

отдача в вашем вопросе заключается в том, что ваше руководство изменения фиксируются, потому что вы выполняете щелчок и изменение при выполнении действия с помощью точки и щелчка в браузере, но ваш программный метод только изменяет элемент управления формы, но не щелчок первым.

Итак, как решить эту проблему с помощью автоматизации VBA через IE?

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

в основном вам нужно "нажать" на элемент формы, который вы хотите изменить , а затем обновить значение элемента управления. Надеюсь, что бит "щелчок" будет означать, что обновления viewmodel нокаута за "изменение", и оттуда данные модели будут записаны в базу данных (или что-то еще):

ваш пример флажка:

If InStr(ExtractedName, "NewPermit") > 0 Then
// hopefully this will get knockout to apply the required binding before your change the value
objElement.Click
objElement.Checked = True

ваш выпадающий пример:

Set DropDown = objHTML.getElementById("ProjectFile-AccreditedCertifierId")
// hopefully this will get knockout to apply the required binding before your change the value
Dropdown.Click
DropDown.selectedIndex = 1

надеюсь, что это поможет-довольно 3-Трубная проблема! Удача.


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

если веб-сайт будет реализовывать простую (чистую) HTML-форму для отправки запроса POST, ваше решение будет в порядке. Но глядя на HTML вы поделились

<label data-bind="text: ProjectFile().ProposalDpLabel()"></label>

на data-bind уже предполагает, что данные собираются / отправляются библиотекой. (Напр. офф использует этот атрибут). Эта библиотека теперь может собирать данные где-то, и это может быть вызвано событием" click "или" key " в JavaScript. Собранная информация затем может быть сохранена в скрытом элементе DOM, как предложено GCSDC или непосредственно в переменной JavaScript.

теперь я бы предложил выяснить, какая структура JavaScript используется на этой странице, проверив источник HTML. В какой-то момент должно быть

<script src="<fancy js framework>.js"></script>

тег в HTML, который должен дать вам имя базы. (На самом деле может быть несколько тегов такого рода, включая пользовательские файлы JavaScript. Эти теги не обязательно должны быть в начале HTML-документа и могут быть разбросаны по всему документу, поэтому вам может потребоваться поиск script в документе HTML. Одной из них должна стать основная фреймворк, на который отправляется запрос. Если вы не уверены, какой из них будет, вы должны google все из них и выяснить.)

затем исследуйте, как запрос POST (возможно, Ajax) отправляется в коде JavaScript на этой странице, с справка из документации фреймворка. А затем отправьте запрос, выполнив пользовательский JavaScript из VBA на этой странице; как это можно сделать, показано в этой пост.

кроме того, вы можете попытаться вызвать событие click (или key) на входах формы, чтобы фреймворк поверил, что вы действительно ввели его; как это можно сделать, показано в этом в должности, но это может работать не во всех случаях.