I have a form in MS Access that I have to fill very often. I would like to automate filling the from.
As I am just a user, I don't have access to the database itself, it's password protected. I would like just to fill the fields in the form, without submitting it or creating a new record in the database.
So what I need is: form opens, the fields are already filled and I manually click Submit button.
I attach the screen of a part of a form to show what I mean.
screen of the form
I know how the form is called in the base - frm_MainManu.
What is more I am in general new to PowerShell, so maybe what I have now (and is below) is completely wrong (or maybe not?).
What I have now is:
$FormFile = "FileWithForm"
$oAccess = New-Object -com Access.Application
$oAccess.Visible=$true
$oAccess.OpenCurrentDataBase($FormFile)
$oAccess.DoCmd.OpenForm('frm_MainMenu')
$AccForm = $oAccess.Forms.Item("frm_MainMenu")
$AccForm.Controls.Item("Reference_3").value = "Refvalue"
After executing the code I get an following error:
You cannot call a method on a null-valued expression.
At line:12 char:1
+ $AccForm.Controls.Item("Reference_3").value = "Refvalue"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The file with the form opens, as I understand there is a problem with filling the fields?
How do I do it?
Thank you!
I don't use powershell, so take that into consideration but after some testing it looks like once you get into the database you must use the Docmd object to do everything. For instance:
$Fullpath = "C:\folder1\folder2\Desktop\anotherfolder\mydbname.accdb"
$oAccess = New-Object -Com Access.Application
$oAccess.Visible=$true
$oAccess.OpenCurrentDataBase($Fullpath)
$oAccess.DoCmd.OpenForm('frm_MainMenu')
'From here continue using DoCmd to set the control
$oAccess.DoCmd.SetProperty("Reference_3",10,"Refvalue")
it looks like they haven't dotted the i's and crossed the t's for instance PowerShell didn't recognize the acPropertyEnum so I had to use 10. see https://learn.microsoft.com/en-us/office/vba/api/access.docmd.setproperty
I had a database lying around that was protected by a password form that loaded automatically but powershell could access the database. The password form came up but Powershell just ignored it.
inportant note: you will need the unique names for each form and control in access as the . operator wasn't working inside power shell. Usually that is just the controls name but for instance the unique name for a form will usually be Form_theformsname. To find an objects unique name in Access use the object browser which can be found by going to the visual basic window and hitting F2.
Related
I'm trying to build a script to ease the access mirroring.
I'm comparing access groups of two users and then displaying only those that the second user is missing.
I have two List Views:
First - Filled in with access groups
Second - Empty view where I want to copy a group name.
I managed to copy the name from the first to second list view although I'm struggling with creating a validation.
Here's the code I have:
Function Add-ItemListView($Item){
if($firstItem -eq $true){
$userGroupsListView.Items.Add($Item)
$global:firstItem = $false
}
else{
foreach($i in $userGroupsListView.Items){
$itemText = $i.Name
if ($itemText -ne $Item){
$userGroupsListView.Items.Add($Item)
}
}
}
}
I think it's actually checking if there already exists an item with the same name, but I'm getting an error message:
Collection was modified; enumeration may not execute.
I will appreciate every direction or tip.
Also is there any documentation for ListView in Powershell?
I could find a bunch of helpful guides and documentation but for C#
I need to support database logging.
For that I decided to use nlog because it brings database support.
But first of all I need to setup the configuration programatically.
As far as I understood it I have to set the layout for the target.
But the class "DatabaseTarget" does not have any property related to Layout :/.
var dbTarget = new DatabaseTarget();
dbTarget.ConnectionString = LogConnectionString;
dbTarget.CommandType = System.Data.CommandType.StoredProcedure;
dbTarget.CommandText = "exec dbo.InsertLog #level=${level}, #callSite=${callsite}, #message=${message}, #stackTrace=${stacktrace}, #machinename=${machinename}, #processname=${processname}";
Is the layout definition really necessary for the DatabaseTarget. If so how do I set it programatically?
Additionally I want to pass some information. But I am not sure how I can assign those informations for the procedure.
As far as I understood it I can assign those variables:
https://github.com/nlog/nlog/wiki/Layout-Renderers
But NLog support generic arguments with his Log Method. It looks like this:
_nLog.Log<AJourFaultLevel>(ConvertLogLevel(logEntry.Level), logEntry.Message, logEntry.Fault);
How can I assign the passed "logEntry.Fault" value for my stored procedure?
Best regards
Your current log-statement injects logEntry.Fault as parameter into string.Format(logEntry.Message, logEntry.Fault):
_nLog.Log<AJourFaultLevel>(ConvertLogLevel(logEntry.Level), logEntry.Message, logEntry.Fault);
If you are using NLog 4.5 then you can use structured-logging where you can name the parameter like this:
_nLog.Log<AJourFaultLevel>(ConvertLogLevel(logEntry.Level), "Fault occurred: {AJourFaultLevel}", logEntry.Fault);
Then you can access the named parameter using ${event-properties:item=}:
dbTarget.CommandText = "exec dbo.InsertLog #level=${level}, #callSite=${callsite}, #message=${message}, #stackTrace=${stacktrace}, #machinename=${machinename}, #processname=${processname}, #faultLevel=${event-properties:item=AJourFaultLevel}";
I need to create file screen exception in powershell using the FSRM Api, I am using this script to create the cuota but I am having trouble to commit the object.
Because I haven't achieved to meet the requirement to modify AllowedFileGroups property :(
$FSRMObject = New-Object -Com Fsrm.FsrmFilescreenManager
$createFileScreenException = $FSRMObject.CreateFileScreenException("c:\")
$createFileScreenException.AllowedFileGroups("Text Files")
$createFileScreenException.Commit()
This is what I get Listing the Properties and Methods of the Object, in the property definition of AllowedFileGroups I can see that I need to create IFsrmMutableCollection.
Does anyone have an idea of how to create the file screen exception?
AllowedFileGroups is a property, not a method, so I'd expect something like this to work:
$createFileScreenException = $FSRMObject.CreateFileScreenException('c:\')
$createFileScreenException.AllowedFileGroups = 'Text Files'
$createFileScreenException.Commit()
Can't test it, though.
This is how you can create the simplest quota using the FSRM api in powershell, to view more modificable options get the members of the object $quota.
$fsrmQuotaObject = New-Object -Com FSrm.FsrmQuotaManager
$quota = $fsrmQuotaObject.CreateQuota("c:\path")
$quota.ApplyTemplate("Select template")
$quota.Commit()
I have a report in SSRS, which has a parameter in it. For each possibility in the parameter, I need an Excel file. This comes down to 50 Excel files. the only way I know to schedule a report is to go to the reporting services home page, go to my report, click manage, click subscriptions > New subscription and to enter a file name, path, user name, password, schedule, parameter and ultimately press OK.
Is there a quicker way to do this, or is there a way which allows me to create the 50 reports more quickly, like copying a subscription or something like that?
try creating a ssis package and running the report for all values of the parameter. i had seen someone do this in my previous company.
data driven subscriptions are available only in enterprise and developer editions - yours could be standard.
You could also write a script in PowerShell or write an app in C#/VB. Here is an example done in PowerShell. Here is an example done in C#. Using either of these approaches, you could programmatically render the reports as you see fit. You can also create subscriptions this way as well.
PowerShell solution to the OP:
# Create a proxy to the SSRS server and give it the namespace of 'RS' to use for
# instantiating objects later. This class will also be used to create a report
# object.
$reportServerURI = "http://<SERVER>/ReportServer/ReportExecution2005.asmx?WSDL"
$RS = New-WebServiceProxy -Class 'RS' -NameSpace 'RS' -Uri $reportServerURI -UseDefaultCredential
$RS.Url = $reportServerURI
# Set up some variables to hold referenced results from Render
$deviceInfo = "<DeviceInfo><NoHeader>True</NoHeader></DeviceInfo>"
$extension = ""
$mimeType = ""
$encoding = ""
$warnings = $null
$streamIDs = $null
# Next we need to load the report. Since Powershell cannot pass a null string
# (it instead just passes ""), we have to use GetMethod / Invoke to call the
# function that returns the report object. This will load the report in the
# report server object, as well as create a report object that can be used to
# discover information about the report. It's not used in this code, but it can
# be used to discover information about what parameters are needed to execute
# the report.
$reportPath = "/PathTo/Report"
$Report = $RS.GetType().GetMethod("LoadReport").Invoke($RS, #($reportPath, $null))
# Report parameters are handled by creating an array of ParameterValue objects.
# $excelInput: either pass in as a parameter and run 50 times, or reset
# this value and run it each time with the updated excel file
$excelInput = "<ExcelFile>";
$parameters = #()
$parameters += New-Object RS.ParameterValue
$parameters[0].Name = "Excel Input File"
$parameters[0].Value = $excelInput
# Add the parameter array to the service. Note that this returns some
# information about the report that is about to be executed.
$RS.SetExecutionParameters($parameters, "en-us") > $null
# Render the report to a byte array. The first argument is the report format.
# The formats I've tested are: PDF, XML, CSV, WORD (.doc), EXCEL (.xls),
# IMAGE (.tif), MHTML (.mhtml).
$RenderOutput = $RS.Render('PDF',
$deviceInfo,
[ref] $extension,
[ref] $mimeType,
[ref] $encoding,
[ref] $warnings,
[ref] $streamIDs
)
# Convert array bytes to file and write
$OutputFile = $excelInput + ".pdf"
$Stream = New-Object System.IO.FileStream($OutputFile), Create, Write
$Stream.Write($RenderOutput, 0, $RenderOutput.Length)
$Stream.Close()
On this question I solved the problem of querying Google Datastore to retrieve stuff by user (com.google.appengine.api.users.User) like this:
User user = userService.getCurrentUser();
String select_query = "select from " + Greeting.class.getName();
Query query = pm.newQuery(select_query);
query.setFilter("author == paramAuthor");
query.declareParameters("java.lang.String paramAuthor");
greetings = (List<Greeting>) query.execute(user);
The above works fine - but after a bit of messing around I realized this syntax in not very practical as the need to build more complicated queries arises - so I decided to manually build my filters and now I got for example something like the following (where the filter is usually passed in as a string variable but now is built inline for simplicity):
User user = userService.getCurrentUser();
String select_query = "select from " + Greeting.class.getName();
Query query = pm.newQuery(select_query);
query.setFilter("author == '"+ user.getEmail() +"'");
greetings = (List<Greeting>) query.execute();
Obviously this won't work even if this syntax with field = 'value' is supported by JDOQL and it works fine on other fields (String types and Enums). The other strange thing is that looking at the Data viewer in the app-engine dashboard the 'author' field is stored as type User but the value is 'user#gmail.com', and then again when I set it up as parameter (the case above that works fine) I am declaring the parameter as a String then passing down an instance of User (user) which gets serialized with a simple toString() (I guess).
Anyone any idea?
Using string substitution in query languages is always a bad idea. It's far too easy for a user to break out and mess with your environment, and it introduces a whole collection of encoding issues, etc.
What was wrong with your earlier parameter substitution approach? As far as I'm aware, it supports everything, and it sidesteps any parsing issues. As far as the problem with knowing how many arguments to pass goes, you can use Query.executeWithMap or Query.executeWithArray to execute a query with an unknown number of arguments.