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) на входах формы, чтобы фреймворк поверил, что вы действительно ввели его; как это можно сделать, показано в этом в должности, но это может работать не во всех случаях.