Does the textbox that is generated when creating a detail view not count as a textbox? - vba

My code searches for certain numbers in textboxes and replaces them. The code however does not change the number if it is in a textbox that is created from a detail view(see figure 1). Do these not count as textboxes?
Figure 1
Dim Totalsheets As Integer
Dim target_text As String
Dim FirstPage As Integer
Dim replace_text As String
Dim result As String
Dim n As Integer 'count No. of text frames changed
Dim i As Integer 'count views for the sheet
Dim x As Integer 'takes the value of the first page of the old config
Dim y As Integer 'takes the value of the total number of sheets of the old config
Dim z As Integer 'takes the value of the number that needs to be added to update the zoning
Dim a As String 'takes the value of the letter found in the zoning box
Dim b As Integer
n = 0
Set osheets = odoc.Sheets
Set osheets = osheets.Item("DRAFT") 'makes sure only sheet "DRAFT" is edited
Set oViews = osheets.Views
Totalsheets = Totalsheets1.Value 'draws value from the textbox
FirstPage = FirstPage1.Value 'draws value from the textbox
For i = 3 To oViews.Count 'scans through all views in sheet
Set oView = oViews.Item(i)
Set oTexts = oView.Texts
For Each SrcText In oTexts 'scans through all text in view
x = FirstPage
y = Totalsheets
b = x + y
Do Until x = b + 1
z = x + Totalsheets
a = "A"
Do Until a = "[" 'goes from A to Z
result = SrcText.Text
target_text = " " & x & a 'gets space in front and letter at back to ensure only zone box are updated
replace_text = " " & z & a
If InStr(result, target_text) Then
result = Replace(result, target_text, replace_text)
SrcText.Text = result
n = n + 1
End If
a = Chr(Asc(a) + 1)
Loop
x = x + 1
Loop
Next
Next

Although the detail view identifier is a DrawingText, it does not belong to the DrawingTexts-collection.
You could access the DrawingText by searching in the view.
Better would be to rename the property of the view.
EDIT:
Example for using the (slower) selection:
Set oSel = oDoc.Selection
oSel.Clear
oSel.Add oView
oSel.Search "CATDrwSearch.DrwText,sel"
for i = 1 to oSel.Count2
Set oDrwText = oSel.Item2(i).Value
'do something with the text
next

Related

vb.net efficiently finding byte sequence in byte array

so I am creating a piece of software that in short, has a list of original byte sequences and new sequences that those bytes need to be changed into, kinda like this in text form "original location(currently irrelevant as sequence can be in different places) $ 56,69,71,73,75,77 : 56,69,71,80,50,54"
I already have code that works fine, however there can be up to 600+ of these sequences to find and change and in some cases it is taking a really really long time 15 mins +, i think it is down to how long it is taking to find the sequences to them change so i am trying to find a better way to do this as currently it is unusable due to how long it takes.
I have copied the whole code for this function below in hopes one of you kind souls can have a look and help =)
Dim originalbytes() As Byte
Dim fd As OpenFileDialog = New OpenFileDialog()
fd.Title = "Select the file"
fd.Filter = "All files (*.*)|*.*|All files (*.*)|*.*"
fd.FilterIndex = 2
If fd.ShowDialog() = DialogResult.OK Then
TextBox2.Text = fd.FileName
originalbytes = File.ReadAllBytes(fd.FileName)
End If
Dim x As Integer = 0
Dim y As Integer = 0
Dim textbox1array() = TextBox1.Lines
Dim changedbytes() = originalbytes
Dim startvalue As Integer = 0
Dim databoxarray() As String
Dim databoxarray2() As String
While x < textbox1array.Length - 1
'for each change to make
databoxarray = textbox1array(x).Replace(" $ ", vbCr).Replace(" : ", vbCr).Split
databoxarray2 = databoxarray(1).Replace(",", vbCr).Split
Dim databox2bytes() As String = databoxarray2
'copy original bytes line to databox2 lines
y = 0
While y < (originalbytes.Length - databox2bytes.Length)
'repeat for all bytes in ori file - size of data to find
If originalbytes(y) = databox2bytes(0) Then
startvalue = y
Dim z As String = 1
Dim samebytecounter As Integer = 1
While z < databox2bytes.Length
'repeat for all ori bytes
If originalbytes(y + z) = databox2bytes(z) Then
samebytecounter = samebytecounter + 1
End If
z = z + 1
End While
If samebytecounter = databox2bytes.Length Then
'same original data found, make changes
Dim bytestoinsert() As String = databoxarray(2).Replace(",", vbCr).Split
Dim t As Integer = 0
While t < bytestoinsert.Length
changedbytes(startvalue + t) = bytestoinsert(t)
t = t + 1
End While
End If
End If
y = y + 1
End While
x = x + 1
End While
File.WriteAllBytes(TextBox2.Text & " modified", changedbytes)
Let 's take a look at that inner while loop in your code, there are some things that can be optimized:
There is no need to check the total length all the time
Dim length as Integer = originalbytes.Length - databox2bytes.Length
While y < length
'repeat for all bytes in ori file - size of data to find
If originalbytes(y) = databox2bytes(0) Then
startvalue = y
z is not necessary, samebytecounter does exactly the same
Dim samebytecounter As Integer = 1
This while loop is a real bottleneck, since you always check the full length of your databox2bytes, you should rather quit the while loop when they don't match
While samebytecounter < databox2bytes.Length AndAlso originalbytes(y + samebytecounter ) = databox2bytes(samebytecounter )
samebytecounter = samebytecounter + 1
End While
This seems fine, but you already splitted the data at the top of your while loop, so, no need to create another array that does the same operation again
If samebytecounter = databox2bytes.Length Then
'same original data found, make changes
Dim t As Integer = 0
While t < databoxarray2.Length
changedbytes(startvalue + t) = databoxarray2(t)
t = t + 1
End While
End If
End If
y = y + 1
End While
For the rest I would agree that the algorithm you created is hugely inefficient, theoretically your code could have been rewritten like eg: (didn't really test this code)
Dim text = System.Text.Encoding.UTF8.GetString(originalbytes, 0, originalbytes.Length)
dim findText = System.Text.Encoding.UTF8.GetString(stringToFind, 0, stringToFind.Length)
dim replaceWith = System.Text.Encoding.UTF8.GetString(stringToSet, 0, stringToSet.Length)
text = text.Replace( findText, replaceWith )
dim outbytes = System.Text.Encoding.UTF8.GetBytes(text)
which would probably be a huge time saver.
For the rest your code seems to be created in such a way that nobody will really understand it if it's laying around for a month or so, I would say, including yourself

Doubles will not output in DataGridView

I have a DataGridView that I want to fill with values that are Doubles. The DataGridView filled fine when the values were strings, but now it outputs System.Double[] in the first column and nothing in any other column. I know the conversion is working because I can print the double values to the console. How do I format all columns programmatically? (I don't want to use the designer)
My code:
Dim cols() as String = {"col1", "col2", "col3"} ' this goes on for 33 cols
Dim currentRow As String()
Dim row() As Double
Dim c As Integer
DataGridView1.Rows.Clear()
DataGridView1.ReadOnly = True
DataGridView1.DefaultCellStyle.Format = "G"
DataGridView1.ColumnCount = 33
For c = 0 To (cols.Length - 1)
DataGridView1.Columns(c).Name = cols(c)
Next
While Not at EndOfFile ' This line and the next are semi-pseudocode, but it's the same idea
read/parse line into currentRow
Dim x As Integer
For x = 0 To (currentRow.Length - 1)
ReDim Preserve row(x)
Double.TryParse(currentRow(x), row(x))
Next
With Me.DataGridView1.Rows
.Add(row)
End With
Screenshot of the output:
You can first add the row to the grid, then loop through your array to add the information to each cell.
Dim i as integer = DataGridView1.Rows.Add
For x As Integer = 0 to row.Count - 1
DataGridView1.Rows(i).Cells(x).Value = row(x)
Next

I want to align Dynamic pictureboxs with Dynamic Labels

Here is my function that allows me to get from a webpage the image link for my PictureBoxs and the title for my labels
Public Shared Function getPics(website As String, pattern As String)
Dim tempTitles As New List(Of String)()
Dim tempTitles2 As New List(Of String)()
Dim lestitres As New List(Of titlesclass)
Dim webClient As New WebClient()
webClient.Headers.Add("user-agent", "null")
Dim counter As Integer = 0
Dim counter2 As Integer = 0
Dim counter3 As Integer = 0
Dim counter4 As Integer = 1
Dim counter5 As Integer = 0
Dim counter6 As Integer = 0
'If the website happens to go offline, at least your application wont crash.
Dim content As String = webClient.DownloadString(website)
Dim query = From title In Regex.Matches(content, pattern).Cast(Of Match)
Select New With {Key .Link = String.Concat("http://www.gamestop.com", title.Groups("Data").Value),
Key .Title = title.Groups("Dataa").Value}
For Each letitre In query.Distinct
'MsgBox(letitre.Link & " ======= " & letitre.Title)
Next
'For Each title As Match In (New Regex(pattern).Matches(content)) 'Since you are only pulling a few strings, I thought a regex would be better.
' Dim letitre As New titlesclass
' letitre.Link = title.Groups("Data").Value
' letitre.Title = title.Groups("Dataa").Value
' lestitres.Add(letitre)
' 'tempTitles2.Add(title.Groups("Dataa").Value)
'Next
Dim titles = tempTitles.Distinct().ToArray() 'remove duplicate titles
'Dim titles2 = tempTitles2.Distinct().ToArray()
Dim titles2 = lestitres.Distinct().ToArray()
lestitres.Clear()
'For Each title As titlesclass In titles2
For Each letitre In query.Distinct
'ListBox.Items.Add(title) 'what you do with the values from here is up to you.
Dim ImageInBytes() As Byte = webClient.DownloadData(letitre.Link)
Dim ImageStream As New IO.MemoryStream(ImageInBytes)
Dim MyPic As New PictureBox
Dim MyLab As New Label
If (counter2 > 0 AndAlso ((counter2 Mod 4 = 0) OrElse counter3 = 1)) Then
counter3 = 1
counter4 += 1
If (counter2 Mod 4 = 0) Then
counter5 = 0
counter6 += 170
End If
MyPic.Location = New Point(counter5, MyPic.Location.Y + counter6)
MyLab.Location = New Point(counter5, MyPic.Location.Y + counter6)
If counter4 = 4 Then
counter3 = 0
End If
counter5 += 200
Else
MyPic.Location = New Point(counter, MyPic.Location.Y)
MyLab.Location = New Point(counter, MyPic.Location.Y)
End If
counter += 200
counter2 += 1
MyPic.SizeMode = PictureBoxSizeMode.AutoSize
MyLab.Text = letitre.Title
MyPic.Image = New System.Drawing.Bitmap(ImageStream)
Form2.Controls.Add(MyPic)
Form2.Controls.Add(MyLab)
Next
End Function
The class named titlesclass contain two elements which i will store my Link and Title in :
Public Class titlesclass
Public Property Link As String
Public Property Title As String
End Class
And My little button does all the work
Dim websiteURL1 As String = "http://www.gamestop.com/collection/upcoming-video-games"
Class1.getPics(websiteURL1, "<img src=""(?<Data>[^>]*)""><p>(?<Dataa>[^>]*)<br>")
What i'm trying to do is to show 4 pictureboxs per row with the lables right bellow each picture , for now some labels doesn't show , some shows just in the right place and some shows very far bellow ! I tested the values i'm getting with a Message Box and it shows me the informations in the order i need , i'm not sure if i screw up in the x,y values or if it's something else ...
Edit : I can already show the 4 pictureboxes per row , the labels also , but the Y of some labels isn't well adjusted it can go far far bellow !
Here is some pictures that will help you to understand my situation Don't mind the buttons and listboxs , it's just for the test :
My list containt a lot of pictures , so i just showed you some when the thing work kind of well , when it shows couple of rows far from the designed picture
http://img110.xooimage.com/files/f/a/d/picture1-5239f7c.png
http://img110.xooimage.com/files/8/f/8/picture-2-5239f7e.png
http://img110.xooimage.com/files/4/7/b/picture-3-5239f80.png
http://img110.xooimage.com/files/f/0/f/picture4-5239f82.png
So I cleaned the way you where generating the position of the PictureBox by using a row principle and increment:
Note:
If you need space at the top to add information start the row count at 1 instead of 0
Note 2:
Here the image dimensions are harcoded but you could use dynamic ones which would be more fluid. I just cleaned the positioning code not the rest.
Replace your function by this one:
Public Shared Sub getPics(website As String, pattern As String)
Dim tempTitles As New List(Of String)()
Dim tempTitles2 As New List(Of String)()
Dim lestitres As New List(Of titlesclass)
Dim webClient As New WebClient()
webClient.Headers.Add("user-agent", "null")
Dim counter As Integer = 0
Dim counter2 As Integer = 0
Dim counter3 As Integer = 0
Dim counter4 As Integer = 1
Dim counter5 As Integer = 0
Dim counter6 As Integer = 0
'If the website happens to go offline, at least your application wont crash.
'Handle default proxy
Dim proxy As IWebProxy = WebRequest.GetSystemWebProxy()
proxy.Credentials = CredentialCache.DefaultCredentials
webClient.Proxy = proxy
Dim content As String = webClient.DownloadString(website)
Dim query = From title In Regex.Matches(content, pattern).Cast(Of Match)
Select New With {Key .Link = String.Concat("http://www.gamestop.com", title.Groups("Data").Value),
Key .Title = title.Groups("Dataa").Value}
Dim titles = tempTitles.Distinct().ToArray() 'remove duplicate titles
Dim titles2 = lestitres.Distinct().ToArray()
lestitres.Clear()
'Count Items
Dim item As Integer = 0
'Count Row
Dim row As Integer = 0
'image: 222*122
For Each letitre In query.Distinct
Dim ImageInBytes() As Byte = webClient.DownloadData(letitre.Link)
Dim ImageStream As New IO.MemoryStream(ImageInBytes)
Dim MyPic As New PictureBox
Dim MyLab As New Label
'x = numéro item fois largeur image
'y = numéro de ligne fois hauteur image
MyPic.Location = New Point(item * 222, row * 122)
MyLab.Location = New Point(item * 222, row * 122)
MyPic.SizeMode = PictureBoxSizeMode.AutoSize
MyLab.Text = letitre.Title
MyPic.Image = New System.Drawing.Bitmap(ImageStream)
Form1.Controls.Add(MyPic)
Form1.Controls.Add(MyLab)
'Bring Labels to front
For Each ctrl As Control In Form1.Controls
'If the control is of type label
If TypeOf ctrl Is Label Then
'Then bring to front
ctrl.BringToFront()
End If
Next
'Increment the item count
item = item + 1
'If item is multiple of 4 or could check 4 then
If item Mod 4 = 0 Then
'Reset counter
item = 0
'Increment Row
row = row + 1
End If
Next
End Sub
Example return:

VB.NET RichTextBox and TextBox Separation

For my company, we receive our time sheets in the following format
Name:Hours
Name:Hours
Name:Hours
I have the Timesheet.txt loading into the RichTextBox1 fine, but, I want when I click a button to load them into two different textboxes. I want the Names to load into TextBox1 and Hours to load into TextBox2
Then it deletes the line. It will go onto the next line when I click the button again.
Any help?
Simple, but will do:
Dim sInput As String = "Name:10"
Dim sSplitArray() As String = sInput.Split(New Char() {":"c})
Dim sName As String = sSplitArray(0)
Dim sHours As String = sSplitArray(1)
String's Split function splits a string up by the character you pass to it.
So if you have this:
sInput = "Name:10:Zebra:Kazaam"
When you split that string by the ":" separator, it will give you an array with:
Name
10
Zebra
Kazaam
Hope that this will give the complete solution for your problem
Dim x, y As Integer
Dim textbox1() As TextBox
x = 430
y = 265
Dim str As String
Dim result(), output(1) As String'str=RitchText1.text 'load input string to str
result = str.Split(System.Environment.NewLine) ' split into array based on new line
For i As Integer = 0 To result.Length - 1 'execute up to array limit
output = result(i).Split(":") 'split again based on :
textbox1(i).Text = output(0) 'Name part into dynamic textbox 1
textbox1(i).Location = New Point(x, y)
textbox1(i + 1).Text = output(1) 'Name part into dynamic textbox 2
textbox1(i + 1).Location = New Point(x + 40, y)
Me.Controls.Add(textbox1(i))
textbox1(i).Visible = True
Me.Controls.Add(textbox1(i + 1))
textbox1(i + 1).Visible = True
y = y + 20
Next

Overwrite a string from the middle

I am trying to make a function to create textboxes. I need to know if there is a way to replace the end of a string with the new number.
While x <= tbnumberofitems
Dim x As Integer = 0 ' looop count '
Dim y As Integer = 1 ' name count'
Dim label1name As String = "label"
Dim textbox1name As String = "textbox"
While x <= tbnumberofitems
y = y + 1
If x = 0 Then y = 1
Convert.ToString(y)
Dim label1 As New Label
label1.Name = label1name & y
'Code to create label box
Dim textbox1 As New TextBox
textbox1.Name = textbox1name & y
'code to create text box
x = x + 1
End While
This is what I currently have. What I need now is a way to make it where when the loop runs the next time, it changes the name to textbox2 and label2 on 3rd loop label 3 and textbox 3, etc. If that is not clear enough what I am trying to do is make it where the numberofitems, make it 5, creates 5 labels and 5 textboxes through the program.
Basicly Like this ..
For x as Integer = 1 to tbnumberofitems
'Code to create label
Dim lbl As New Label
lbl.Name = "label" & format(x)
lbl.Location = New Point(10, x*20)
Me.Controls.Add(lbl)
'Code to create textbox
Dim tb As New TextBox
tb.Name = "TextBox" & format(x)
tb.Location = New Point(100, x*20)
Me.Controls.Add(tb)
Next