convert visio vba method into c# - c#

Hello I would like to convert this vba method into C#. I am trying to get the IDs of a selection and print them out. In particular I am having trouble converting the GetIDs() method(a built in method within visio vba) into C#.
Public Sub getCapabilityRectIDs()
Dim vsoSelection1 As Visio.Selection
Dim selectionIDs() As Long
Set vsoSelection1 = Application.ActiveWindow.Page.CreateSelection(visSelTypeByLayer, visSelModeSkipSuper, "Capability")
Application.ActiveWindow.Selection = vsoSelection1
Call vsoSelection1.GetIDs(selectionIDs)
For i = 0 To UBound(selectionIDs)
Debug.Print selectionIDs(i)
Next i
End Sub
This is what I have so far in C#
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Visio = Microsoft.Office.Interop.Visio;
class Program
{
static void Main(string[] args)
{
//create the object that will do the drawing
VisioDrawer Drawer = new VisioDrawer();
Drawer.selectShpLayer("Capability");
}
}
class VisioDrawer
{
public Visio.Application VisApp;
public static Visio.Page acPage;
public Visio.Selection LayerSelection;
public VisioDrawer()
{
//create the application
VisApp = new Visio.Application();
VisApp.Documents.Open(#"............. - abc.vsdm");
ActiveDoc = VisApp.ActiveDocument;
acPage = VisApp.ActivePage;
}
public void selectShpLayer (string layerName){
Int i = 0;
long[] lngRowIDs;
//this selects the shapes of the selected layer
LayerSelection = acPage.CreateSelection(Microsoft.Office.Interop.Visio.VisSelectionTypes.visSelTypeByLayer, Microsoft.Office.Interop.Visio.VisSelectMode.visSelModeOnlySuper,layerName);
LayerSelection.GetIDs(lngRowIDs);
for (i = 0; i < lngRowIDs.Length; i++)
{
Debug.Write(lngRowIDs[i]);
}
}
}
Thanks in advance!

I created a visio doc and drew 3 simple shapes. I then created a layer called "cool" and added those 3 shapes to it.
I don't understand enough about the shape selection, you had visSelModeOnlySuper which may work for you, but did not work for the case I created. The default is visSelModeSkipSuper (which worked for me)
Here's the API page that describes how to use the createSelection:
https://msdn.microsoft.com/en-us/library/office/ff765565.aspx
Here is my sample code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Visio = Microsoft.Office.Interop.Visio;
class Program
{
static void Main(string[] args)
{
//create the object that will do the drawing
VisioDrawer Drawer = new VisioDrawer();
Drawer.selectShpLayer("cool");
}
}
class VisioDrawer
{
public Visio.Application VisApp;
public static Visio.Page acPage;
public Visio.Selection LayerSelection;
public VisioDrawer()
{
//create the application
VisApp = new Visio.Application();
VisApp.Documents.Open(#"c:\temp\trial.vsdm");
acPage = VisApp.ActivePage;
}
public void selectShpLayer(string layerName)
{
int i = 0;
int[] lngRowIDs;
Array lngRowIDArray;
//this selects the shapes of the selected layer
LayerSelection = acPage.CreateSelection(Microsoft.Office.Interop.Visio.VisSelectionTypes.visSelTypeByLayer, Microsoft.Office.Interop.Visio.VisSelectMode.visSelModeSkipSuper, layerName);
LayerSelection.GetIDs(out lngRowIDArray);
lngRowIDs = (int[])lngRowIDArray;
for (i = 0; i < lngRowIDs.Length; i++)
{
Debug.Write("Object ID: " + lngRowIDs[i].ToString() + "\n");
}
}
}
And it produces this output:
Object ID: 1
Object ID: 2
Object ID: 3
If you change the debug line to this:
Debug.Write("Object ID: " + lngRowIDs[i].ToString() + " -- " + acPage.Shapes.ItemFromID[i].Name + "\n");
The output gets even more useful:
Object ID: 1 -- ThePage
Object ID: 2 -- Circle
Object ID: 3 -- Rectangle

Related

ref list isn't modified outside command class

I would like one class to modify the list fields of another class. I pass both list fields as references. The problem is, one list is modified in the end, and second is not. I don't understand why. I wanted to check my idea with a minimal working example, where everything works fine:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _20190424_ref_list_del
{
class Program
{
static void Main(string[] args)
{
ListManager testObj = new ListManager();
testObj.startJob();
}
}
class ListManager
{
private List<int> ListToExpand;
private List<int> ListToShorten;
public ListManager()
{
ListToExpand = new List<int>() { 1, 2, 3 };
ListToShorten = new List<int>() { 1, 2, 3 };
}
public void startJob()
{
EditList editObj = new EditList(ref ListToExpand, ref ListToShorten);
editObj.doJob();
System.Diagnostics.Debug.Print("List to expand:");
foreach (int x in ListToExpand)
{
System.Diagnostics.Debug.Print(x.ToString());
}
System.Diagnostics.Debug.Print("List to shorten:");
foreach (int x in ListToShorten)
{
System.Diagnostics.Debug.Print(x.ToString());
}
}
}
class EditList
{
private List<int> ListToExpand;
private List<int> ListToShorten;
public EditList(ref List<int> listToExpand, ref List<int> listToShorten)
{
ListToExpand = listToExpand;
ListToShorten = listToShorten;
}
public void doJob()
{
ListToExpand.Add(4);
ListToShorten.RemoveAt(0);
}
}
}
The main idea is:
Init two lists
Expand first and shorten another.
Check if there is an effect outside the working class, which modifies lists.
For this reason, I'm using ref. But the same approach in my real app fails. I have two lists too. One to be expanded, second to be shortened.
Let me explain what part of my code does: There is a list of samples from a Modbus device. Some of the samples require to be joined into bigger ones (because some of the values are so large that have values of int32 which need to be stored in two int16 registers).
I have a class with the Command design pattern which works as follows:
Create a Command object which takes:
(ref) input list of single samples
list of samples to be joined
(ref) list of samples joined to double ones
Build double samples
Remove single samples which have been joined
While testing, the list of double samples are filled, but the list of single ones isn't shortened. I don't understand why, because it looks like I'm using the same approach as in the minimal working example. Can you tell me what's wrong?
Test Case:
namespace put_samples_into_dbTests.Unit.Commands
{
[TestClass]
public class GetDoubleSamples
{
List<Sample> SingleSamples;
List<PatternSample32> SamplesPattern;
List<Sample32> ResultSamples;
int MaxSources = 2;
int MaxObjects = 3;
[TestInitialize]
public void TestInit()
{
SingleSamples = new List<Sample>();
SamplesPattern = new List<PatternSample32>();
ResultSamples = new List<Sample32>();
for (byte i = 1; i <= MaxSources; i++)
{
for (byte k = 2; k <= MaxObjects; k++)
{
SamplesPattern.Add(new PatternSample32(i, k, 1, 2));
}
}
}
[TestMethod]
public void BuildFrom1Set()
{
int howManySamples32 = MaxSources * (MaxObjects-1);
int howManySamples = MaxSources* ((1 + MaxObjects) * MaxObjects / 2) - howManySamples32 *2;
DateTime dateTime = DateTime.Now;
for (byte i = 1; i <= MaxSources; i++)
{
for (byte k = 1; k <= MaxObjects; k++)
{
for (byte l = 1; l <= k; l++)
{
SingleSamples.Add(new Sample(dateTime, i, k, l, 1, true));
}
}
}
Command command = new GetDoubleSamples(ref SingleSamples, SamplesPattern , ref ResultSamples );
command.Execute();
Assert.AreEqual(howManySamples, SingleSamples.Count); // [!]
Assert.AreEqual(howManySamples32, ResultSamples.Count);
}
Now, do take a look at my GetDoubleSamples command:
public class GetDoubleSamples : Command
{
private List<Sample> SingleSamples;
private List<PatternSample32> DoubleSamplesPattern;
private List<Sample32> ResultSamples;
private List<Sample> ProcessedSamples;
public GetDoubleSamples (ref List<Sample> singleSamples, List<PatternSamples32> doubleSamplesPattern, ref List<Sample32> resultSamples)
{
SingleSamples = singleSamples;
doubleSamplesPattern = doubleSamplesPattern;
ResultSamples = resultSamples;
ProcessedSamples = new List<Sample>();
}
public void Execute()
{
SortSamples();
foreach (List<Sample> samplesSet in GenerateSets())
{
ResultSamples.AddRange(BuildDoubles(samplesSet ));
}
DeleteProcessedSamples();
}
private void DeleteProcessedSamples()
{
SingleSamples = SingleSamples.Except(ProcessedSamples).ToList();
}
}
And the problem is, when I check for the amount of created double samples - it's okay. But the same (I suppose) kind of list of simple samples isn't reduced of processed samples. When I debug the code, I see that inside the class the mentioned list is modified. But once I get outside Execute methods and get outside Command class, I lose that modified list and get back to the original one. Just as if my list wasn't passed as a reference.
Do you have any idea what might be wrong?
Any suggestions, also about rearranging my test method, will be appreciated! :-)

Link combo box and parallel array

I need help linking or mapping a combo box to a parallel array in C#. I have a class project where I need to create a payroll system that displays the Net Pay after taxes.
I want to link parallel arrays that have all the employee information needed for payroll to the option selected in the combo box. I feel like I almost have it, but I don't know how to link the option selected from the combo box and the parallel arrays I have set up.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ZNSPayrollSystem
{
public partial class ZNSPayrollSystem : Form
{
public ZNSPayrollSystem()
{
InitializeComponent();
string[] arr = { "001 Peters", "002 Barnes", "003 Harris" };
cboEmp.DataSource = arr.ToArray();
}
private void btnCalc_Click(object sender, EventArgs e)
{
//parallel arrays
int[] empID = { 001, 002, 003 };
string[] empName = { "James Peters", "Sarah Barnes", "Candice Harris" };
double[] hrsWorked = { 40, 40, 40 };
double[] empWage = { 55.50, 65.50, 75.70 };
//declarations
double dblTaxRate = 8.2 / 100;
double dblNetPay;
double dblGrossPay;
double dblTaxWithheld;
dblGrossPay = hrsWorked[] * empWage[];
dblTaxWithheld = dblGrossPay * dblTaxRate;
dblNetPay = dblGrossPay - dblTaxWithheld;
txtGross.Text = dblGrossPay.ToString();
txtTax.Text = dblTaxWithheld.ToString();
txtNetPay.Text = dblNetPay.ToString();
}
}
}
Use the SelectedIndex property of the Combobox:
int i = cboEmp.SelectedIndex;
if (i != -1)
{
dblGrossPay = hrsWorked[i] * empWage[i];
}
i == -1 means nothing is selected. You may want to handle this separately to avoid getting any exceptions.

Issues with syntax c#, unable to use ojects/call get, set,

I am new to C# and have been working on a project for a maze game in a haunted house context.After researching different approaches I have decided to go with using objects and a linked list. However, despite weeks of trying I am struggling with the code and have gotten to the point after hours of reading articles and watching online tutorials that I am now more confused that ever before. I want to go with this approach rather than an array as I feel like this is more efficient and more OOP.
I was thinking of going with a simple if/else structure but for this level of coding I feel it would be too messy.
Any help, constructive criticism or ideas would be highly appreciated as I don't want to give up after so many hours spent on it but I feel its getting to that point. This is my code so far.
Thanks in advance :)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace maze_3
{//open namespace
class Room
{//open class room
private string RoomName;
private Room N = null; // so that when i set the links they are automatically null unless i specify in main
private Room E = null;
private Room S = null;
private Room W = null;
public Room X { get; private set; } // the software implemented this
public void setName(string N) // so that i am able to set the name of the room
{
RoomName = N;
}
public void setN(Room X) // sets the north direction between the objects of the rooms
{
N = X;
}
public void setE(Room X)
{
E = X;
}
public void setW(Room X)
{
W = X;
}
public void setS(Room x)
{
S = X;
}
public Room getN() // want to get a direction from the user, in this case they would input a north direction
{
return N;
}
public Room getE()
{
return E;
}
public Room getS()
{
return S;
}
public Room getW()
{
return W;
}
static void Main(string[] args)// it is asking for a ; here but also says that I should declare it as extern, partial etc
class chamber// its telling me that a ; is expected ???
{//open class chamber
chamber gh = new chamber();// my objects that are the rooms in the haunted house.
chamber kit = new chamber();
chamber Pan = new chamber();
chamber Dun = new chamber();
chamber dr = new chamber();
chamber lib = new chamber();
chamber din = new chamber();
chamber sr = new chamber();
chamber weap = new chamber();
chamber tow = new chamber();
chamber gal = new chamber();
chamber tr = new chamber();
gh.RoomName("Great Hall"); //to set the object name as the Great Hall, all get and set links were available in class
gh.setW(dr); ///I want to set a west direction between my object gh to dr
gh.SetS(kit);// to set a south link between my two objects
dr.setName("Drawing Room");//states that all my setlinks are not valid in the current context- this is for all
dr.setS(lib); //it states the ; is not a valid token in class, struct or interface
kit.setName("Kitchen");// it states that my objects e.g kit is not valid in this current context-this is for all
kit.setS(pan);
pan.setName("Pantry");
pan.SetE(dun); /// this is a dead end in the game
lib.setName("Library ");
lib.setE(din);
din.setName("Dining Room");
din.setN(sr);
din.setE(gal);
din.setS(weap); //dead end in the game
sr.setName("Smoking Room");
sr.setE(tow);//dead end
gal.setName("Treasure Room");
gal.setS(tr)
/// </summary> so i wanted to have the actual game play to follow a linked list with a if else structure.
int finish = 0;
string choice;
Room current;
current=gh;
while (finish !=1) (finish ==0) //im confused as to which condition is best to use.
{Console.WriteLine("You are in room " + current.getRoomname() + "and you can move ");
    if( current.getN() != null)
        Console.WriteLine("North (N) ");
    if( current.getE() != null)
        Console.WriteLine("East (E) ");
Console.WriteLine("Please enter the direction you wish to go in ");
    string choice = Console.ReadLine();
    if (choice[0] == 'E') // or alternative means of getting in a choice from a string
        current = current.getE();// to be able to move to next 'current'room
// i was going to do this for all the options.
if(current == tr // ie last room
exit = 1;
Console.Writeline ("Well done you have found the treasure room");
}//close chamber
}//close class rooom
} //close namespace
You created a class object which doesn't have a main(). A project only has one main. So you either need to make the Room the main() in the application or removed main method from the Room Class. See my code below for changes.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace maze_3
{
class Program
{
static void Main(string[] args)
{
Room home = new Room("White House");
home.CreateRoom("W", "West Wing");
}
}
class Room
{//open class room
private string RoomName;
private Room N = null; // so that when i set the links they are automatically null unless i specify in main
private Room E = null;
private Room S = null;
private Room W = null;
private List<Chamber> chambers = new List<Chamber>();
public Room() { }
public Room(string name)
{
this.RoomName = name;
}
public void CreateRoom(string direction, string name)
{
Room newRoom = new Room();
newRoom.RoomName = name;
switch (direction)
{
case "N":
N = newRoom;
break;
case "E":
E = newRoom;
break;
case "S":
S = newRoom;
break;
case "W":
W = newRoom;
break;
}
}
}//close class rooom
public class Chamber// its telling me that a ; is expected ???
{//open class chamber
string name = "";
}//close chamber
}

Find certain text in PDF, then return page number found on to another section NOTE: Uses Docotic.pdf

In the following code, the user will input a search string (barcodedata). That string will then be truncated to the first 5 characters, and used as the jobnumber. The jobnumber, is also the name of the pdf I will be scanning for the barcodedata.
What I would like, is for the 'Find it' button to execute the below code, then return the value found to startpagedata.
I can't tell if the program just isn't actually scanning the PDF for the search string, or if the value simply isn't returning to the program.
using BitMiracle.Docotic.Pdf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
using Acrobat;
namespace BarCodeReader
{
public partial class Form1 : Form
{
public string stringsToFind;
public string pathtofile;
public Form1()
{
InitializeComponent();
}
private void barcodedata_TextChanged(object sender, EventArgs e)
{
stringsToFind=barcodedata.Text;
pathtofile = "C:\\" + StringTool.Truncate(barcodedata.Text, 5) + ".pdf";
jobnumberdata.Text = StringTool.Truncate(barcodedata.Text, 5);
}
private void label4_Click(object sender, EventArgs e)
{
}
private void jobnumberdata_TextChanged(object sender, EventArgs e)
{
jobnumberdata.Text = jobnumberdata.Text.TrimStart('0');
Console.WriteLine(jobnumberdata.Text);
}
private void startpagedata_TextChanged(object sender, EventArgs e)
{
Console.WriteLine(startpagedata.Text);
}
private void piecesdata_TextChanged(object sender, EventArgs e)
{
}
private void FindIt_Click(object sender, EventArgs e)
{
PdfDocument pdf = new PdfDocument(pathtofile);
for (int i = 0; i < pdf.Pages.Count; i++)
{
string pageText = pdf.Pages[i].GetText();
int count = 0;
int lastStartIndex = pageText.IndexOf(stringsToFind, 0, StringComparison.CurrentCultureIgnoreCase);
while (lastStartIndex != -1)
{
count++;
lastStartIndex = pageText.IndexOf(stringsToFind, lastStartIndex + 1, StringComparison.CurrentCultureIgnoreCase);
}
if (count != 0)
startpagedata.Text = Convert.ToString(lastStartIndex);
}
}
}
public static class StringTool
{
/// <summary>
/// Get a substring of the first N characters.
/// </summary>
public static string Truncate(string source, int length)
{
if (source.Length > length)
{
source = source.Substring(0, length);
}
return source;
}
/// <summary>
/// Get a substring of the first N characters. [Slow]
/// </summary>
public static string Truncate2(string source, int length)
{
return source.Substring(0, Math.Min(length, source.Length));
}
}
}
What is your problem with this code? If FindIt_Click is not executed on click then probably you don't associate it with the "Find it" button.
The code in FindIt_Click looks quite correct except several things:
It may not do what you expect. It returns the last index in the text of the last page where the search string was found. But may be you expect the index of the last page where the search string was found?
You may use pageText.LastIndexOf method to quickly find lastStartIndex.
Don't forget to Dispose PdfDocument instance. E.g. use using keyword:
using (PdfDocument pdf = new PdfDocument(pathtofile))
{
...
}
In order to use Docotic.pdf you can use Acrobat.dll to find the current page number. First of all open the pdf file and search the string using
Acroavdoc.open("Filepath","Temperory title")
and
Acroavdoc.FindText("String").
If the string found in this pdf file then the cursor moved into the particular page and the searched string will be highlighted. Now we use Acroavpageview.GetPageNum() to get the current page number.
Dim AcroXAVDoc As CAcroAVDoc
Dim Acroavpage As AcroAVPageView
Dim AcroXApp As CAcroApp
AcroXAVDoc = CType(CreateObject("AcroExch.AVDoc"), Acrobat.CAcroAVDoc)
AcroXApp = CType(CreateObject("AcroExch.App"), Acrobat.CAcroApp)
AcroXAVDoc.Open("File path", "Original document")
AcroXAVDoc.FindText("String is to searched", True, True, False)
Acroavpage = AcroXAVDoc.GetAVPageView()
Dim x As Integer = Acroavpage.GetPageNum
MsgBox("the string found in page number" & x)

C# / Windows Forms: error cs1519

I'm working on a graphics transformation program, setting up a listbox to read in the names of files in a directory. The code is based off an example from my instructor, so I thought it would work fine, but it seems to create errors everywhere. I googled "error CS1519: Invalid token ‘,’ in class, struct, or interface member declaration", but what I found looked unapplicable. Here it is:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Transformer
{
public partial class Transformer : Form
{
/* Initialize parameters */
private bool drawAxes = true;
private bool drawGrid = true;
private List<ObjectSettings> dispObjects = new List<ObjectSettings>();
/* Initialize form */
public Transformer()
{
InitializeComponent();
}
private void Transformer_Load(object sender, EventArgs e)
{
}
/* Populate available objects listbox */
private int selFile = 0;
private string currentDir = Directory.GetCurrentDirectory();
// errors start around here
private string[] fileEntries = Directory.GetFiles(currentDir+#"\Objects");
foreach (string s in fileEntries) {
int start = s.LastIndexOf(#"\");
int end = s.LastIndexOf(#".");
availObjectsListBox.Items.Add(s.Substring(start + 1, end - start - 1));
} // end foreach
}
}
That's because you need to put:
foreach (string s in fileEntries) {
int start = s.LastIndexOf(#"\");
int end = s.LastIndexOf(#".");
availObjectsListBox.Items.Add(s.Substring(start + 1, end - start - 1));
}
in a function.
Maybe you can do something like:
private void Transformer_Load(object sender, EventArgs e)
{
int selFile = 0;
string currentDir = Directory.GetCurrentDirectory();
string[] fileEntries = Directory.GetFiles(currentDir+#"\Objects");
foreach (string s in fileEntries) {
int start = s.LastIndexOf(#"\");
int end = s.LastIndexOf(#".");
availObjectsListBox.Items.Add(s.Substring(start + 1, end - start - 1));
} // end foreach
}
Note that you put the foreach loop inside the Transformer_Load function; of course, you can put it in any other function. And note that there is no modifier (private) in front of selFile, currentDir and fileEntries variable.
Look where the errors start!
You cant have statements in the class body. It needs to be in a method/property/constructor.

Categories