good morning everyone
I`m having a little issue with a dgv. Im trying to fill it with the result of a function that shows the name of the files in a folder and the amount of lines each file has.
But for some reason im having a null vaule on the datagrid and i dont know how to remove it. I`ve been doing this without much knowledge of vb.net or coding whatsoever so any help would be greatly apreciated
Here is the code:
Imports System
Imports System.Linq
Imports System.Collections
Imports System.IO
Imports System.IO.StreamReader
Imports System.IO.DirectoryInfo
Public Class MainForm
'asigna la var como datatable
Dim results1 As New DataTable
Private Sub Boton_Buscar_Click(sender As System.Object, e As System.EventArgs) Handles Boton_Buscar.Click
'muestra el dialogo y guarda el dir
FBD1.ShowDialog()
TextBox1.Text = FBD1.SelectedPath
FSW1.Path = TextBox1.Text
'indica el datasource al datagrid
Try
DGV1.DataSource = GetLineCount()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
'devuelve archivos y su num de lineas
Public Function GetLineCount() As DataTable
results1.Columns.Add(0)
results1.Columns.Add(1)
'array para los tipos de archivo
Dim MyFileArray As [String]() = New [String](7) {"*.txt", "*.doc", "*.docx", "*.odt", "*.pdf", "*.rtf", _
"*.csv", "*.vb"}
'array para los directorios
Dim MyDirectoryArray As [String]() = New [String](0) {TextBox1.Text}
' loop directorios
For Each sd As [String] In MyDirectoryArray
Dim dir As New DirectoryInfo(sd)
'loop los tipos de archivos
For Each sFileType As [String] In MyFileArray
'loop los archivos ante el contador
For Each file__1 As FileInfo In dir.GetFiles(sFileType)
Dim LineCount = System.IO.File.ReadAllLines(file__1.FullName).Count()
'alimenta el datagrid con los datos nuevos
results1.Rows.Add()
results1.Rows.Add.Item(0) = "FileName: " & file__1.FullName
results1.Rows.Add.Item(1) = "LineCount: " & LineCount
Next
Next
Next
Return results1
End Function
End Class
And here is the output im getting:
Any help is very welcome, have a good day
The reason you are getting null values is that you're trying to add the row by one cell at a time.
Instead of
results1.Rows.Add()
results1.Rows.Add.Item(0) = "FileName: " & file__1.FullName
results1.Rows.Add.Item(1) = "LineCount: " & LineCount
Try
results1.Rows.Add("FileName: " & file__1.FullName, "LineCount: " & LineCount)
Your current code adds three rows instead of 1 each time: first an empty row, then a row with cell(0) filled and then null, and then a row with null and then cell(1) filled.
Related
I have an unbound datagridview, set the option to allow user to add row to True, and all I want is that once I "complete" a row, the datagridview automatically should create a new empty row, so I set the method
DataGridView1.Rows.Add()
in the DataGridView1_Leave event, but once the row is finished and exception comes out:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll - Unable to complete this operation in this event handler
What does it mean? It should be plain simple code, but I don't know how to solve
Here is the situation:
That's the recipient DataGridView. When I'm on the first blank row (which is created by the AllowUserToAddRow = true) and I press F3 a modal form is opened with another DataGridView containing products to select
and here's the code for the KeyDown event in the recipient DataGridView
Private Sub DataGridView1_KeyDown(sender As Object, e As KeyEventArgs) Handles DataGridView1.KeyDown
If e.KeyCode = Keys.F3 Then
If frmZoomArticoli.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim codart As String = frmZoomArticoli.DataGridView1.CurrentCell.Value.ToString()
RicercaxCodiceArticolo(codart)
End If
End If
End Sub
Here the sub RicercaxCodiceArticolo(codart) which fills the recipient DataGridView with the selected product:
Private Sub RicercaxCodiceArticolo(ByVal codiceart As String)
Dim strsql As String
Dim cmd As SqlCommand
Dim source As New BindingSource
'Dichiariamo le variabili che ospitano i dati di riga
Dim codice As String
Dim descrizione As String
Dim unitamisura As String
Dim quantita As Double = 1.0
Dim codiceiva As Double
Dim costobase As Double
Dim prezzobase As Double
Dim costoultimo As Double
Dim giacenza As Double
Dim sconto1 As Double
Dim sconto2 As Double
connection.Open()
strsql = "SELECT CODICEARTICOLO AS 'Codice', DESCRIZIONEARTICOLO AS 'Descrizione', UNITAMISURA AS 'Um', CODICEIVA AS 'Iva' " _
& ", COSTOBASE AS 'Costo', PREZZOBASE AS 'Prezzo', SCONTO1 As 'Sc1', SCONTO2 As 'Sc2', COSTOULTIMO AS 'CostoUlt' " _
& ", BARCODE AS 'Barcode', NOTEARTICOLO AS 'Note' ,CATEGORIAARTICOLO AS 'Categ.Art.', GIACENZA AS 'Giacenza' " _
& ", FORNITOREPREF AS 'Fornit. Pref.' FROM Articoli " _
& " WHERE CODICEARTICOLO = '" & codiceart & "'"
cmd = New SqlCommand()
cmd.CommandText = strsql
cmd.CommandType = CommandType.Text
cmd.Connection = connection
source.DataSource = cmd.ExecuteReader()
'Assegniamo i dati letti nel bindingsource alle variabili
codice = source.Current!Codice
descrizione = source.Current!Descrizione
unitamisura = source.Current!Um
codiceiva = Convert.ToDouble(source.Current!Iva)
costobase = Convert.ToDouble(source.Current!Costo)
prezzobase = Convert.ToDouble(source.Current!Prezzo)
costoultimo = Convert.ToDouble(source.Current!Costoult)
giacenza = Convert.ToDouble(source.Current!Giacenza)
sconto1 = Convert.ToDouble(source.Current!Sc1)
sconto2 = Convert.ToDouble(source.Current!Sc2)
'Riempiamo le celle con i dati estratti dal BindingSource
With DataGridView1.CurrentRow
.Cells("grdCodice").Value = codice
.Cells("grdDescrizione").Value = descrizione
.Cells("grdUM").Value = source.Current!Um
.Cells("grdQuantita").Value = quantita
If TipoMovimento = "Carico" Then
.Cells("grdPrezzoUnitario").Value = source.Current!CostoUlt
Else
.Cells("grdPrezzoUnitario").Value = source.Current!Prezzo
End If
.Cells("grdSconto1").Value = sconto1
.Cells("grdSconto2").Value = sconto2
.Cells("grdSconto3").Value = 0.0
.Cells("grdSconto4").Value = 0.0
'Per calcolare il prezzo totale di riga dobbiamo tenere presente le
'informazioni che abbiamo gia' in anagrafica, ovvero il costo/prezzo
'e gli sconti
'Blocco di controllo sul tipo movimento
If TipoMovimento = "Carico" Then
If sconto1 > 0 Then
.Cells("grdPrezzoTotale").Value = quantita * (costoultimo * (costoultimo * sconto1 / 100))
Else
.Cells("grdPrezzoTotale").Value = quantita * costoultimo
End If
ElseIf TipoMovimento = "Scarico" Then
If sconto1 > 0 Then
.Cells("grdPrezzoTotale").Value = quantita * (prezzobase * (prezzobase * sconto1 / 100))
Else
.Cells("grdPrezzoTotale").Value = quantita * prezzobase
End If
End If
.Cells("grdAliquotaIva").Value = codiceiva
End With
connection.Close()
End Sub
and that's the result in the recipient DataGridView:
now, suppose that I don't want to edit the selected row because I don't need to edit quantity, or price, or whatever, but I just want to insert a new row to keep inserting other products. When I tab until the end of the row I want to create a new row, and that's why I wrote the DataGridView1.Rows.Add() in the RowLeave event of the DataGridView, but that's where the exception occurs:
I'm sorry for all the descriptions are in italian, but if you need any other details feel free to ask.
If there's nothing I can do all that remains is to add a button outside the DataGridView which adds a new row from there. Any other solution is welcomed.
Is there some reason you do not use a DataSource for the grid? Then you could simply add the row to the DataSource.
If you insist on manually adding the rows, then the problem you currently have is that the code is never “adding” a new row to the grid. The code simply uses the grids CurrentRow to set the values. This may work but the grids “new” row will not get created.
It is questionable to use the grids CurrentRow in this manner... So instead of using the grids CurrentRow for this, I suggest you “add” a new row in the RicercaxCodiceArticolo method. Something like below should add the new row and the “new-new” empty row should be at the bottom…
Dim newRowIndex As Int32
newRowIndex = DataGridView1.Rows.Add()
With DataGridView1.Rows(newRowIndex)
.Cells("grdCodice").Value = codice
.Cells("grdDescrizione").Value = descrizione
'.....
End With
I have a function that receives a PDF file from the desktop. What I want is that, before saving the PDF, deactivate the clipboard so that they cannot copy the text or images of the document.
My code:
Dim NombreArchivo As String = System.IO.Path.GetFileName(File1.PostedFile.FileName) ' obtiene nombre archivo
Dim docsubido As New Document()
Dim SaveLocation As String = Server.MapPath("Pdf") & "\" & NombreArchivo ' obtiene ruta donde se guardara
If Not File1.PostedFile Is Nothing And File1.PostedFile.ContentLength > 0 Then
Try
File1.PostedFile.SaveAs(SaveLocation)
Response.Write("El archivo ha sido cargado.")
Catch Exc As Exception
Response.Write("Error: " & Exc.Message)
End Try
Else
Response.Write("Seleccione un archivo para cargar.")
End If
End Sub
Finally this was the solution to be able to disable the property of copying and pasting of a PDF only the option to print
Imports iTextSharp.text.pdf
Imports iTextSharp.text.pdf.PdfStamper
Private Sub Submit1_ServerClick(sender As Object, e As EventArgs) Handles Submit1.ServerClick
Dim NombrePdfEntrada As String = System.IO.Path.GetFileName(File1.PostedFile.FileName) ' obtiene nombre archivo
Dim SaveLocation As String = Server.MapPath("Pdf") & "\" & NombrePdfEntrada ' obtiene ruta donde se guardara
If Not File1.PostedFile Is Nothing And File1.PostedFile.ContentLength > 0 Then
Try
File1.PostedFile.SaveAs(SaveLocation)
Dim ArchivoCargado As New PdfReader(SaveLocation)
Dim rutasalida As New FileStream(Server.MapPath("Pdf") & "\Nuevo" & NombrePdfEntrada, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)
Dim stampArchivoOutput As New PdfStamper(ArchivoCargado, rutasalida)
Dim passdue As String = ""
Dim arraydueño() As Byte = System.Text.Encoding.ASCII.GetBytes(passdue)
Dim passinv As String = ""
Dim arrayinvitado() As Byte = System.Text.Encoding.ASCII.GetBytes(passinv)
stampArchivoOutput.SetEncryption(False, passdue, passinv, PdfWriter.ALLOW_PRINTING)
stampArchivoOutput.Close()
ArchivoCargado.Close()
Response.Write("El archivo ha sido cargado.")
Catch Exc As Exception
Response.Write("Error: " & Exc.Message & Exc.HelpLink
)
End Try
Else
Response.Write("Seleccione un archivo para cargar.")
End If
End Sub
End Class
I need to make a loop to look at a lot of mp3 files and getting their naturalDuration property using a mediaElement. The problem is that mediaElement need some time to load every single file and .source property works like async process (I think) because I have to click two times on below code if I want to obtain naturalDuration property. First click I have just 00:00:00 value, second clik give me real value.
Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
mediaElement.Source = New Uri("\\Mac\Home\Desktop\NOVEDADES01\AbrahamMateo-OldSchool.mp3")
textBlock.Text = mediaElement.NaturalDuration.ToString
End Sub
If I try to wait after .Source instruction, the application keeps on loop.
Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
mediaElement.Source = New Uri("\\Mac\Home\Desktop\NOVEDADES01\AbrahamMateo-OldSchool.mp3")
Do
Loop Until mediaElement.NaturalDuration.TimeSpan.TotalSeconds > 0
textBlock.Text = mediaElement.NaturalDuration.ToString
End Sub
I also have try set .source through an async process and wait for mediaOpenend event, but it look like mediaElemento can not end until the first click was ending
How could I get real value of naturalDuration inside one single process or function just after set .source property and without playing the file?
Thanks a lot!!
Ok, late and may be not so elegant but this was my solution for getting duration of a mp3 file. I used MusicProperties Class.
Public Function infoMP3(elfichero As String) As String
Dim salida As String = ""
Dim miTask = Task.Run(Async Function() As Task(Of String)
Dim musicFile As StorageFile = Await StorageFile.GetFileFromPathAsync(elfichero)
Dim FileProperties As StorageItemContentProperties = musicFile.Properties
Dim musicFileProperties As MusicProperties = Await FileProperties.GetMusicPropertiesAsync()
Dim tiempo = musicFileProperties.Duration
Dim horas As String
If tiempo.Hours < 10 Then
horas = "0" & tiempo.Hours.ToString
Else
horas = tiempo.Hours.ToString
End If
Dim minutos As String
If tiempo.Minutes < 10 Then
minutos = "0" & tiempo.Minutes.ToString
Else
minutos = tiempo.Minutes.ToString
End If
Dim segundos As String
If tiempo.Seconds < 10 Then
segundos = "0" & tiempo.Seconds.ToString
Else
segundos = tiempo.Seconds.ToString
End If
Dim autor = musicFileProperties.Artist
Dim titulo = musicFileProperties.Title
Dim presalida As String = "[" & horas & ":" & minutos & ":" & segundos & "];[" & titulo & "];[" & autor & "] " & elfichero
Return presalida
End Function)
miTask.Wait()
salida = miTask.Result
Return salida
End Function
To get access to the files later on Windows 10, you have to save permission for the files and/or folders. Do this when you select them.
...
Dim listToken = Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.Add(rutaS)
...
where rutaS is an SotorageFolder object.
User, 1,2,3,4,5,6,7,8,9
Joe, 34,3,32,1,3
John, 32,2
Tom, 98,34,23
Dave, 56, 53, 32,1,22,6,5
I have this csv file that I would like to put in a 2d array.
Private Sub GetElement()
'Read the data from the cv file
Try
Dim fileIn As String = "mel.csv"
Dim fileRows(), fileFields() As String
Dim count As Integer = 0
textBox.Text = String.Empty
If File.Exists(fileIn) Then
Dim fileStream As StreamReader = File.OpenText(fileIn)
fileRows = fileStream.ReadToEnd().Split(Environment.NewLine)
For i As Integer = 0 To fileRows.Length - 1
fileFields = fileRows(i).Split(",")
If fileFields.Length >= 2 Then
For x As Integer = 0 To fileFields.Length - 1
If x = 0 Then
For e As Integer = 0 To fileFields.Length
ele.Add(fileFields(e))
listBox.Items.Add(ele(e))
Next
End If
Next
count = count + 1
End If
Next
Else
textBox.Text = fileIn & " not found."
End If
Catch ex As Exception
textBox1.Text = ex.Message
End Try
End Sub
I was able to receive the first line only and then I have added it to a list box. In the MainWindow class I have declared two list of string to store the column and rows.
try this....
Imports System.Data.OleDb
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim folder = "Path to your CSV folder (do not include the file name here)"
Dim CnStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & folder & ";Extended Properties=""text;HDR=No;FMT=Delimited"";"
Dim dt As New DataTable
' change Test.csv to your csv file name here
Using Adp As New OleDbDataAdapter("select * from [Test.csv]", CnStr)
Try
Adp.Fill(dt)
Catch ex As Exception
End Try
End Using
DataGridView1.DataSource = dt
End Sub
End Class
this will import the CSV file then display it straight into a DataGridView control (list box has problem with columns)... hope that helps
Why don't you work with objects since you are working with an OO'programing language . It would be simple and more optimised if you created a new class . And then create a new object after reading each line . Dim u as new User(x,y,z...) And to organise your data, use a hashtable or a linkedlist (don't know if it's called like this for vb.net). Then you can fill in your listbox from objects that are in your hashtable or linkedlist.
I have in my project 2 buttons to import from Excel and export to Excel and a datagridview. I can import Excel files with no problem but when I export from datagridview to Excel and try to re-import that file I only get just one column header with "F1" in it:
This is the code for export button:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
'Creamos las variables
Dim exApp As New Excel.Application
Dim exLibro As Excel.Workbook
Dim exHoja As Excel.Worksheet
Try
'Añadimos el Libro al programa, y la hoja al libro
exLibro = exApp.Workbooks.Add
exHoja = exLibro.Worksheets.Add()
' ¿Cuantas columnas y cuantas filas?
Dim NCol As Integer = DataGridView1.ColumnCount
Dim NRow As Integer = DataGridView1.RowCount
'Aqui recorremos todas las filas, y por cada fila todas las columnas
'y vamos escribiendo.
For i As Integer = 1 To NCol
exHoja.Cells.Item(1, i) = DataGridView1.Columns(i - 1).Name.ToString
Next
For Fila As Integer = 0 To NRow - 1
For Col As Integer = 0 To NCol - 1
exHoja.Cells.Item(Fila + 2, Col + 1) = DataGridView1.Item(Col, Fila).Value
Next
Next
'Titulo en negrita, Alineado al centro y que el tamaño de la columna
'se ajuste al texto
exHoja.Rows.Item(1).Font.Bold = 1
exHoja.Rows.Item(1).HorizontalAlignment = 3
exHoja.Columns.AutoFit()
'Aplicación visible
exApp.Application.Visible = True
exHoja = Nothing
exLibro = Nothing
exApp = Nothing
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
What can I do to solve it??
Thanks.
For an import from Excel where the top image depicts what happens using SELECT *
The bottom image shows using field aliasing as shown in the code below
Code to read sheet data using aliasing
Dim dt As New DataTable
Dim FileName As String = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SampleData.xlsx")
Using cn As New OleDb.OleDbConnection With
{
.ConnectionString = ConnectionHelper.ConnectionString(FileName, "No")
}
Console.WriteLine(cn.ConnectionString)
' .CommandText = "SELECT F1 As FirstName, F2 As MiddleName, F3 As LastName FROM [PeopleData$] ORDER BY F3",
Using cmd As New OleDb.OleDbCommand With
{
.CommandText = "SELECT F1 As FirstName, F2 As MiddleName, F3 As LastName FROM [Sheet1$] ORDER BY F3",
.Connection = cn
}
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
DataGridView1.DataSource = dt
Code for above to set connection
Public Module ConnectionHelper
Public Function ConnectionString(ByVal FileName As String) As String
Dim Builder As New OleDb.OleDbConnectionStringBuilder
If IO.Path.GetExtension(FileName).ToUpper = ".XLS" Then
Builder.Provider = "Microsoft.Jet.OLEDB.4.0"
Builder.Add("Extended Properties", "Excel 8.0;IMEX=2;HDR=No;")
Else
Builder.Provider = "Microsoft.ACE.OLEDB.12.0"
Builder.Add("Extended Properties", "Excel 12.0;IMEX=2;HDR=No;")
End If
Builder.DataSource = FileName
Return Builder.ConnectionString
End Function
Public Function ConnectionString(ByVal FileName As String, ByVal Header As String) As String
Dim Builder As New OleDb.OleDbConnectionStringBuilder
If IO.Path.GetExtension(FileName).ToUpper = ".XLS" Then
Builder.Provider = "Microsoft.Jet.OLEDB.4.0"
Builder.Add("Extended Properties", String.Format("Excel 8.0;IMEX=1;HDR={0};", Header))
Else
Builder.Provider = "Microsoft.ACE.OLEDB.12.0"
Builder.Add("Extended Properties", String.Format("Excel 12.0;IMEX=1;HDR={0};", Header))
End If
Builder.DataSource = FileName
Return Builder.ConnectionString
End Function
End Module
Note the sheet has no column name, ony data. If the first row had column names the connection would have Yes as argument 2 rather than No as above .ConnectionString = ConnectionHelper.ConnectionString(FileName, "Yes")
I found the solution, the problem wasn´t the Import button, instead it seems to be the Export button because it export the file with some kind of damage. I tried with other code I found (to export) and worked, This is the working code:
Dim stRuta As String = ""
Dim openFD As New OpenFileDialog()
With openFD
.Title = "Seleccionar archivos"
.Filter = "Archivos Excel(*.xls;*.xlsx)|*.xls;*xlsx|Todos los archivos(*.*)|*.*"
.Multiselect = False
.InitialDirectory = My.Computer.FileSystem.SpecialDirectories.Desktop
If .ShowDialog = Windows.Forms.DialogResult.OK Then
stRuta = .FileName
End If
End With
Try
'Dim stConexion As String = ("Provider=Microsoft.ACE.OLEDB.12.0;" & ("Data Source=" & (stRuta & ";Extended Properties=""Excel 12.0;Xml;HDR=YES;IMEX=2"";")))
Dim stConexion As String = ("Provider=Microsoft.ACE.OLEDB.12.0;" & ("Data Source=" & (stRuta & ";Extended Properties=""Excel 12.0;Xml;HDR=YES;IMEX=2"";")))
Dim cnConex As New OleDbConnection(stConexion)
Dim Cmd As New OleDbCommand("Select * From [Hoja1$]")
Dim Ds As New DataSet
Dim Da As New OleDbDataAdapter
Dim Dt As New DataTable
cnConex.Open()
Cmd.Connection = cnConex
Da.SelectCommand = Cmd
Da.Fill(Ds)
Dt = Ds.Tables(0)
Me.DataGridView1.Columns.Clear()
Me.DataGridView1.DataSource = Dt
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, "Error")
End Try
Thank you all :)