run time error in SAP Business One Client - c#

My code has runtime error
Error:
An exception of type 'System.Runtime.InteropServices.COMException' occurred in MatrixFill.exe but was not handled in user code
Additional information: 1). [Microsoft] [SQL Server Native Client 11.0] [SQL Server] Incorrect syntax near 'OCRD'.
I want to connect to sap via c # and fill the matrix
How do I change the code ???
my code:
using System;
using System.Collections.Generic;
using System.Xml;
using SAPbouiCOM.Framework;
namespace MatrixFill
{
[FormAttribute("MatrixFill.Form1", "Form1.b1f")]
class Form1 : UserFormBase
{
public Form1()
{
}
/// <summary>
/// Initialize components. Called by framework after form created.
/// </summary>
public override void OnInitializeComponent()
{
this.Matrix0 = ((SAPbouiCOM.Matrix)(this.GetItem("Item_0").Specific));
this.Button0 = ((SAPbouiCOM.Button)(this.GetItem("btnFill").Specific));
this.Button0.ClickBefore += new
SAPbouiCOM._IButtonEvents_ClickBeforeEventHandler(this.Button0_ClickBefore);
this.OnCustomInitialize();
}
/// <summary>
/// Initialize form event. Called by framework before form creation.
/// </summary>
public override void OnInitializeFormEvents()
{
}
private SAPbouiCOM.Matrix Matrix0;
private void OnCustomInitialize()
{
}
private SAPbouiCOM.Button Button0;
private void Button0_ClickBefore(object sboObject, SAPbouiCOM.SBOItemEventArg pVal, out bool BubbleEvent)
{
BubbleEvent = true;
SAPbobsCOM.Company oCompany = (SAPbobsCOM.Company)Application.SBO_Application.Company.GetDICompany();
SAPbobsCOM.Recordset oRset = (SAPbobsCOM.Recordset)oCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.BoRecordset);
string Query = "select CardCode,CardName,E_Mail sFrom OCRD";
oRset.DoQuery(Query);
if (oRset.RecordCount > 0)
{
for (int i = 0; i < oRset.RecordCount; i++)
{
Matrix0.AddRow();
((SAPbouiCOM.EditText)Matrix0.Columns.Item("colCode").Cells.Item(i + 1).Specific).Value = oRset.Fields.Item("CardCode").Value.ToString();
((SAPbouiCOM.EditText)Matrix0.Columns.Item("colName").Cells.Item(i + 1).Specific).Value = oRset.Fields.Item("CardName").Value.ToString();
((SAPbouiCOM.EditText)Matrix0.Columns.Item("colEmail").Cells.Item(i + 1).Specific).Value = oRset.Fields.Item("E_Mail").Value.ToString();
oRset.MoveNext();
}
}
}
}
}
note:
My form has a matrix with three columns
The matrix is designed in Visual Studio 2015

It's because you have the s just before From near the bottom.
Change this
select CardCode,CardName,E_Mail sFrom OCRD
to
select CardCode,CardName,E_Mail From OCRD
Cheers
Jon

Related

How to use CommandLineParser in a WinForms Project? How to build a custom Help MessageBox?

I'm trying to use the CommandLineParser Library in Version 2.5.0 in a WinForms application.
It works great except for a help screen (MessageBox in that case).
I already figured out that I need to create a own parser and set at least the HelpWriter property to null to create a custom Help Screen.
But when the application is called with --help argument my "Error handler" just get one error instance with a Tag of type CommandLine.ErrorType and a Value of HelpRequestedError
Now how to build the custom Help Screen?
https://github.com/commandlineparser/commandline/wiki/Generating-Help-and-Usage-information
This site suggests to use the Types in CommandLine.Text Namespace but how? There are zero examples how to do it.
Anyone here did something like this?
I have the following code:
namespace myWorkspace
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;
using CommandLine;
using DevExpress.XtraEditors;
using Options;
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
internal static int Main(string[] args)
{
AppDomain.CurrentDomain.SetupInformation.PrivateBinPath = "bin";
WindowsFormsSettings.EnableFormSkins();
WindowsFormsSettings.EnableMdiFormSkins();
WindowsFormsSettings.ForceDirectXPaint();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var parser = new Parser(config =>
{
config.AutoHelp = true;
config.AutoVersion = true;
config.CaseInsensitiveEnumValues = false;
config.CaseSensitive = false;
config.EnableDashDash = true;
config.HelpWriter = null;
config.IgnoreUnknownArguments = true;
//config.MaximumDisplayWidth
config.ParsingCulture = CultureInfo.InvariantCulture;
});
return Parser.Default.ParseArguments<RunOptions>(args)
.MapResult(
RunRunAndReturnExitCode,
RunParsingFailedAndReturnExitCode);
}
private static int RunRunAndReturnExitCode(RunOptions opts)
{
try
{
Application.Run(new MainForm());
}
catch
{
return -1;
}
return 0;
}
private static int RunParsingFailedAndReturnExitCode(IEnumerable<Error> errs)
{
foreach (var err in errs)
{
var locErr = err;
}
return 1;
}
}
}
And on Line var locErr = err; i don't know what to do to get a help screen message i can show in a MessageBox or the like.
CommandLineParser seems to support console output out-of-the-box for help or --help but I have no console app here.
Ok i now figured out a way to do it. Does not seem to be the best way but it works.
I create a StringBuilder instance and put it into a StringWriter instance
private static StringBuilder helpTextBuilder = new StringBuilder();
private static StringWriter helpTextWriter = new StringWriter(helpTextBuilder);
Then I create a new Parser with (at least this) Option(s):
var parser = new Parser(config =>
{
config.HelpWriter = helpTextWriter;
});
In the case of error I can now use what is written into the helpTextBuilder to show a message box.
private static int RunParsingFailedAndReturnExitCode(IEnumerable<Error> errs)
{
MessageBox.Show(helpTextBuilder.ToString());
return 1;
}
So this is now working for me.

Can't Read Data from external Server to Hololens

I have written some code to transfer data from external server to Hololens. I am able to connect Hololens to the server. But I am facing problem in sending the data from server to Hololens. Whenever I call ReadData function it isn't even connected(it prints Not connected).
I am quite new to c# and unity and isn't able to sort out this matter yet.
I am using StreamSocket and DataReader classes to connect and read the data respectively. Function Connect() connects with the server in start() method and then I call ReadData function in update() method to get the data from the server at every frame. I am attaching my code file.
Can you help me out in solving my problem Thanks in advance.
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Net;
using System;
using UnityEngine;
#if !UNITY_EDITOR && UNITY_METRO
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using Windows.Networking;
using Windows.Foundation;
#endif
public class TCPclientRead : MonoBehaviour
{
public string ServerIP = "10.1.2.35";
[Tooltip("The connection port on the machine to use.")]
public int ConnectionPort = 11000;
private string data = "connected" ;
public TextMesh mesh;
private bool connected = false;
#if !UNITY_EDITOR && UNITY_METRO
private StreamSocket networkConnection;
/// <summary>
/// Temporary buffer for the data we are recieving.
/// </summary>
//private byte[] dataBuffer;
public void Connect( )
{
// Setup a connection to the server.
HostName networkHost = new HostName(ServerIP.Trim());
//HostName networkHost = new HostName( IPAddress.Any.ToString());
networkConnection = new StreamSocket();
// Connections are asynchronous.
// !!! NOTE These do not arrive on the main Unity Thread. Most Unity operations will throw in the callback !!!
IAsyncAction outstandingAction = networkConnection.ConnectAsync(networkHost, ConnectionPort.ToString());
AsyncActionCompletedHandler aach = new AsyncActionCompletedHandler(NetworkConnectedHandler);
outstandingAction.Completed = aach;
}
public void NetworkConnectedHandler(IAsyncAction asyncInfo, AsyncStatus status)
{
if (status == AsyncStatus.Completed)
{
connected = true;
// Here Just display connected
}
else
{
connected = false;
Debug.Log("Failed to establish connection. Error Code: " + asyncInfo.ErrorCode);
// In the failure case we'll requeue the data and wait before trying again.
networkConnection.Dispose();
}
}
public void ReadData()
{
if(connected)
{
DataReader reader = new DataReader(networkConnection.InputStream);
reader.InputStreamOptions = InputStreamOptions.Partial;
reader.LoadAsync(512);
data = reader.ReadString(512);
}
}
private void Start()
{
mesh = gameObject.GetComponent<TextMesh>();
Connect();
}
private void Update()
{
if (connected)
{
mesh.text = data;
}
else
mesh.text = "Not Connected";
ReadData();
}
#endif
}
Edit : 1. I have doubt that ReadData() needs to be called asynchronously Therefore I updated the code but it isn't working even now.
2. I am using Unity Editor and I have enabled the required settings and I am able to connect to the server. It's just that I am not able to transfer the data.
3. I am using netcat to create server.
My updated code
delegate void DelegateMethod();
public async void ReadData()
{
if(connected)
{
DataReader reader = new DataReader(networkConnection.InputStream);
reader.InputStreamOptions = InputStreamOptions.Partial;
await reader.LoadAsync(512);
data = reader.ReadString(512);
}
}
public void AsynCall()
{
DelegateMethod dlgt = new DelegateMethod(this.ReadData);
IAsyncResult ar = dlgt.BeginInvoke(null, null);
dlgt.EndInvoke(ar);
}
private void Start()
{
mesh = gameObject.GetComponent<TextMesh>();
Connect();
}
private void Update()
{
if (connected)
{
if(String.IsNullOrEmpty(data))
data = "Improper";
AsynCall();
mesh.text = data;
}
else
mesh.text = "Not Connected";
}
My suspicion is that you have not enabled the UWP Capability "InternetClient" which would prevent it from actually connecting to the remote server. You don't mention what tool chain you are using, but if you are in Unity check under Build Settings -> Publish Settings -> Windows Store -> Publishing Settings -> Capabilities. If you are working in Visual Studio, you can adjust this in the project properties.

C# Windows Service - this keyword error

I have the following code which works fine when I use it within a Windows Forms application, however the application I'm writing needs to run as a Windows service, and when I moved my code into the Windows Service template in Visual Studio 2015 Community Edition, I get the following error.
Cannot implicitly convert type "MyWindowsService.Main" to "System.ComponentModel.ISynchronizeVoke". An explicit conversion exists (are you missing a cast?)
Could anyone shed some light on why I am getting this error, and what I need to do to resolve it?
The code which throws the error is the line below, and it is located within the OnStart method of my main class (named Main.cs). The code is used to create an instance of the DataSubscriber class (AdvancedHMI library).
dataSubscribers[dataSubscriberIndex].SynchronizingObject = this;
It has to have something to do with the fact that the code is in a Windows service template, because using this works perfectly in my forms application running the same code.
UPDATE
Correction, I've attempted to cast this to the required type, and now get the following error on run.
Additional information: Unable to cast object of type 'MyWindowsService.Main' to type 'System.ComponentModel.ISynchronizeInvoke'.
Code:
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (System.ComponentModel.ISynchronizeInvoke)this;
UPDATE
I've included the entire contents of the Main.cs file from my Windows Service application.
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using AdvancedHMIDrivers;
using AdvancedHMIControls;
using MfgControl.AdvancedHMI.Drivers;
using MfgControl.AdvancedHMI.Controls;
using System.Collections.ObjectModel;
namespace PLCHistoricDataHarvester {
public partial class Main : ServiceBase {
private EthernetIPforCLXCom commObject = new EthernetIPforCLXCom();
private globals globals = new globals();
private Dictionary<String, String> operationLines = new Dictionary<String, String>();
private Dictionary<String, String> tags = new Dictionary<String, String>();
private Collection<DataSubscriber> dataSubscribers = new Collection<DataSubscriber>();
private int harvesterQueueCount = 0;
private string harvesterInsertValues = String.Empty;
public Main() {
InitializeComponent();
}
protected override void OnStart(string[] args) {
// Initialize our harvester program
initializeHarvester();
Console.WriteLine("The program has started");
}
protected override void OnStop() {
// Call code when the service is stopped
Console.WriteLine("Program has stopped");
Console.ReadLine();
}
public void initializeHarvester() {
// First, we connect to the database using our global connection object
globals.dbConn.DatabaseName = "operations";
if (!globals.dbConn.IsConnect()) {
// TODO: Unable to connect to database. What do we do?
}
// Second, we connect to the database and pull data from the settings table
globals.initializeSettingsMain();
// Set IP address of PLC
commObject.IPAddress = globals.getSettingsMain("Processor_IP");
// Pull distinct count of our parent tags (Machines ex: Line 1, etc)
operationLines = globals.getOperationLines();
// If we have at least 1 operation line defined...we continue
if (operationLines.Keys.Count > 0) {
//Now we loop over the operation lines, and pull back the data points
int dataSubscriberIndex = 0;
foreach (KeyValuePair<String, String> lines in operationLines) {
int line_id = int.Parse(lines.Key);
string name = lines.Value;
tags = globals.getTags(line_id);
// If we have at least 1 tag for this operation line, we continue...
if (tags.Keys.Count > 0 && tags["tags"].ToString().IndexOf(",") != -1) {
// Create our dataSubscriber object
dataSubscribers.Add(new DataSubscriber());
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
dataSubscribers[dataSubscriberIndex].CommComponent = commObject;
dataSubscribers[dataSubscriberIndex].PollRate = 1000;
dataSubscribers[dataSubscriberIndex].PLCAddressValue = tags["tags"];
dataSubscribers[dataSubscriberIndex].DataChanged += new EventHandler<MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs>(subscribeCallback);
// Increment our dataSubscriberIndex
dataSubscriberIndex++;
}
}
}
}
private void subscribeCallback(object sender, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs e) {
// code removed as it is irrelevant
}
}
}
The error message says this:
An explicit conversion exists (are you missing a cast?)
So add a cast like this:
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
^^^^^^^^^^^^^^^^^^^^
//Add this
If you've got a console app, the easiest way to convert it to a windows service is by using Topshelf, a nuget package which lets you run in either console mode or nt service mode.
Here's the quickstart guide.
We use it to write services all the time and it helps you avoid this kind of fragile shenanigans.

Delete Rows Start in CSV file In SSIS Controlflow Script Task

I have a .csv file that looks like this:
#Example Company
#(999) 999-9999
#http://yourwebsite.com
#Report Date Range: Dec 26, 2013 - Dec 26, 2013
#Exported: Dec 26, 2013
#Twitter : Profile Summary
#Screen Name,Name,Description,Location,Followers,Following,Listed
SctaSa,statisticalgraph,statistical Screen- The official account for your
organization,Saudi Arabia,6775,8,75
So, I need to take specific data from the .csv file to be readable to SSIS Transformation, start from column "Screen Name" and remove the garbage data which start with # , to be look like that
Screen Name,Name,Description,Location,Followers,Following,Listed,Exported,Report Date Range
SctaSa,statisticalgraph,statistical Screen- The official account for your organization,Saudi Arabia,6775,8,75,26-Dec-13,26-Dec-13
i tried to use this C# script but it does not wore file (I'm not an expert in C# so I don't know what the problem is) I tried to use the following script to delete any line start with # but the file dose not transfare to the out put path; could you give me any suggestions?!
#region Namespaces
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
using System.Collections.Generic;
#endregion
namespace ST_a7b941606e0b40aa920bfe13fc81dc81
{
/// <summary>
/// ScriptMain is the entry point class of the script. Do not change the name, attributes,
/// or parent of this class.
/// </summary>
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
protected void Page_Load(object sender, EventArgs e)
{
var lines = new List<string>();
string line;
using (var file = new System.IO.StreamReader("D:\\try.csv"))
{
while ((line = file.ReadLine()) != null)
{
if (line.Length != 0)
{
if (!line.StartsWith("#") )
{
lines.Add(line);
}
}
}
}
File.WriteAllLines("D:\\SCTA_ETL\\try.csv", lines);
}
/// <summary>
/// This method is called when this script task executes in the control flow.
/// Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.
/// To open Help, press F1.
/// </summary>
public void Main()
{
// TODO: Add your code here
Dts.TaskResult = (int)ScriptResults.Success;
}
#region ScriptResults declaration
/// <summary>
/// This enum provides a convenient shorthand within the scope of this class for setting the
/// result of the script.
///
/// This code was generated automatically.
/// </summary>
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
Another way:
File.WriteAllLines(outputPath, File.ReadAllLines("c:\\mycsv.csv").Where(x => !x.StartsWith("#")).ToArray());
You might want to change your logic in the middle:
var lines = new List<string>();
string outputPath = // your output path here
using (var file = new System.IO.StreamReader("c:\\mycsv.csv"))
{
string line;
while ((line = file.ReadLine()) != null)
{
if (!line.StartsWith("#"))
{
lines.Add(line);
}
}
}
File.WriteAllLines(outputPath, lines);
You had been removing all lines that had "#" anywhere inside.
Instead, only add in lines that do not start with "#".
Also, be sure to close and dispose your StreamReader when you are done with it, or just put the whole thing in using section.

How can I get the number of test iterations in a load test from within a load test plugin?

I need to obtain the number of test iterations for a load test from within a load test plugin, where I have an instance of a LoadTest object. I've searched the LoadTest object's properties and it feels like there is a lot missing compared to the treeview editor that is normally used to configure a load test.
I'm already defining the number of test iterations again as a Context parameter and passing that through to my web test, but this feels like a hack because I'm duplicating data.
class MyLoadTestPlugin : ILoadTestPlugin
{
private LoadTest loadTest;
public void Initialize(LoadTest test)
{
loadTest = test;
loadTest.TestStarting += (_, e) =>
{
// Get # of Test Iterations in load test here,
// "loadTest" object does not have nearly as
// many properties as it should, compared to
// the tree view editor.
};
}
}
Use the LoadTestPlugin to read the .loadtest file which is a XML file. Here is an example to read the TotalIterations in the .loadtest file.
using System;
using Microsoft.VisualStudio.TestTools.LoadTesting;
using System.IO;
using System.Xml;
namespace LoadTest
{
public class LoadTestPluginImpl : ILoadTestPlugin
{
LoadTest mLoadTest;
static int TotalIterations;
public void Initialize(LoadTest loadTest)
{
mLoadTest = loadTest;
//connect to the TestStarting event.
mLoadTest.TestStarting += new EventHandler<TestStartingEventArgs>(mLoadTest_TestStarting);
ReadTestConfig();
}
void mLoadTest_TestStarting(object sender, TestStartingEventArgs e)
{
//When the test starts, copy the load test context parameters to
//the test context parameters
foreach (string key in mLoadTest.Context.Keys)
{
e.TestContextProperties.Add(key, mLoadTest.Context[key]);
}
//add the CurrentTestIteration to the TestContext
e.TestContextProperties.Add("TestIterationNumber", e.TestIterationNumber);
//add the TotalIterations to the TestContext and access from the Unit Test.
e.TestContextProperties.Add("TotalIterations", TotalIterations);
}
void ReadTestConfig()
{
string filePath = Path.Combine(Environment.CurrentDirectory, mLoadTest.Name + ".loadtest");
if (File.Exists(filePath))
{
string runSettings = mLoadTest.RunSettings.Name;
XmlDocument xdoc = new XmlDocument();
xdoc.Load(filePath);
XmlElement root = xdoc.DocumentElement;
string xmlNameSpace = root.GetAttribute("xmlns");
XmlNamespaceManager xmlMgr = new XmlNamespaceManager(xdoc.NameTable);
if (!string.IsNullOrWhiteSpace(xmlNameSpace))
{
xmlMgr.AddNamespace("lt", xmlNameSpace);
}
var nodeRunSettings = xdoc.SelectSingleNode(string.Format("//lt:LoadTest/lt:RunConfigurations/lt:RunConfiguration[#Name='{0}']", runSettings), xmlMgr);
//var nodeRunSettings = xdoc.SelectSingleNode(string.Format("//lt:LoadTest", runSettings), xmlMgr);
if (nodeRunSettings != null)
{
TotalIterations = Convert.ToInt32(nodeRunSettings.Attributes["TestIterations"].Value);
}
}
}
}
}
Similarly you can read the other values.
A web test has the current iteration number in webTest.Context.WebTestIteration (and also as a context parameter named $WebTestIteration).
A LoadTest has access to the current iteration number in the TestStartingEventArgs object:
loadTest.TestStarting += ( (sender, e) =>
{
int iteration = e.TestIterationNumber;
};
To prove to myself that these values are the same and that there is no unexpected behaviour like numbers being reused across different scenarios, I (EDIT:re-) wrote these plugins, and it checks out.
(Thanks to #AdrianHHH for pointing out that the previous code was not complete)
public class LoadTestIteration : ILoadTestPlugin
{
List<int> usedTestIterationNumbers = new List<int>();
public void Initialize(LoadTest loadTest)
{
loadTest.TestStarting += (sender, e) =>
{
e.TestContextProperties["$LoadTest.TestIterationNumber"] = e.TestIterationNumber;
System.Diagnostics.Debug.Assert(!usedTestIterationNumbers.Contains(e.TestIterationNumber), "Duplicate LoadTest TestIterationNumber: " + e.TestIterationNumber);
usedTestIterationNumbers.Add(e.TestIterationNumber);
};
}
}
public class TestWebTestIteration : WebTestPlugin
{
public override void PreWebTest(object sender, PreWebTestEventArgs e)
{
int lti = (int)e.WebTest.Context["$LoadTest.TestIterationNumber"];
int wti = e.WebTest.Context.WebTestIteration;
System.Diagnostics.Debug.Assert(lti == wti, String.Format("$LoadTestIteration {0} differs from $WebTestIteration {1}", lti, wti));
}
}

Categories

Resources