Reputation: 520
I have a file folder that contains pdf files. The sql database is not directly related to the files. For example, I have "Invoice_co_355_24636.pdf" and "Invoice_co_355_25127.pdf" in the Invoices folder. I query the database and find that Invoice "24636" is not paid and "25127" is marked paid in full, so I would like to delete "Invoice_co_355_25127.pdf" at that point since it is paid.
So what I'm doing is getting all the file names from the folder, parsing each file to get just the last numbers, (which correlate to the database). If the database shows that one or more of the Invoices has been paid, I would like to delete the file.
I have successfully, (below), been able to parse the server file names as
"InvNo" as the parsed file name, (which corelates to the database), and
"InvNoFull", which is the full database file name that needs to be deleted if it is marked as paid in the database.
But after getting the file names and the parsed file names, I do not know how to actually compare it to the database and then delete. Any help is appreciated.
Dim files() As String = Directory.GetFiles(Server.MapPath("/Contents/Invoices/" + Variable.ToString() + "/Co/" + ddlCo.SelectedValue.ToString() + "/"))
For Each file As String In files
Dim InvNo As String = Path.GetFileNameWithoutExtension(file)
Dim InvNoFull As String = Path.GetFileName(file)
InvNo = InvNo.Substring(InvNo.LastIndexOf("_") + 1, InvNo.Length - InvNo.LastIndexOf("_") - 1)
Dim CnStr As String = (ConfigurationManager.ConnectionStrings("ClientConnectionString").ConnectionString)
Dim adp As SqlDataAdapter = New SqlDataAdapter("select OrderBilling.OrderId from orderBilling Left Outer Join Orders on OrderBilling.OrderId = Orders.OrderId Where Orders.CompanyId = " & ddlCo.SelectedValue.ToString() & " And Orders.OwnerId = " & Variable.ToString() & " And OrderBilling.PaidInFull = 'False'", CnStr)
Dim ds As DataSet = New DataSet()
adp.Fill(ds, "outBill")
For Each Row As DataRow In ds.Tables(0).Rows
For Each Coll As DataColumn In ds.Tables(0).Columns
Dim s As String = Row(Coll.ColumnName).ToString()
If s <> InvNo Then
Dim FileToDelete() As String
FileToDelete = Directory.GetFiles(Server.MapPath("/Contents/Invoices/" + Variable.ToString() + "/Co/" + ddlCo.SelectedValue.ToString() + "/" + InvNoFull))
If System.IO.File.Exists(FileToDelete.ToString()) = True Then
System.IO.File.Delete(FileToDelete.ToString())
'MsgBox("File Deleted")
End If
End If
Next
Next
Next
With help from Mary but this deletes all the files in the folder, but I want it to delete only the files not returned in the database query:
Private Sub DeletePaidInvoices(OwnerID2 As String, CompanyID As String)
Dim InvoicePath = "/Contents/Invoices/" & OwnerID2 & "/Co/" & CompanyID & "/"
Dim files() As String = Directory.GetFiles(Server.MapPath(InvoicePath))
Dim lst = GetInvoiceInfo(CInt(CompanyID), CInt(OwnerID2))
For Each file As String In files
Dim InvNo As String = Path.GetFileNameWithoutExtension(file)
Dim InvNoFull As String = Path.GetFileName(file)
InvNo = InvNo.Substring(InvNo.LastIndexOf("_") + 1, InvNo.Length - InvNo.LastIndexOf("_") - 1)
'Debug.Print(InvNo) 'To check your substring, will not be in release version
For Each i As Integer In lst
Dim s As String = i.ToString()
If s <> InvNo Then
Dim FileToDelete As String
FileToDelete = "Invoice_co_" & CompanyID & "_" & InvNo & ".pdf"
If System.IO.File.Exists(Server.MapPath(InvoicePath & FileToDelete.ToString())) = True Then
System.IO.File.Delete(Server.MapPath(InvoicePath & FileToDelete.ToString()))
End If
End If
Next
Next
End Sub
Upvotes: 0
Views: 212
Reputation: 15091
Call your delete method from, say, a button passing the variable from the user interface.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim CompID = ddlCo.SelectedValue.ToString()
Dim OwnerID = "comes from somewhere"
DeletePaidInvoices(OwnerID, CompID)
End Sub
The delete method gets the file list. I have no idea about Server.MapPath but I assume you do. Next we get a List(Of Integer) representing the results of you database query (the OrderID
's). Next we enter the For
loop. I added a Debug
line to see what is being returned by SubString
code. As you can see it is simpler code to loop through a list.
Private Sub DeletePaidInvoices(OwnerID As String, CompanyID As String)
Dim InvoicePath = $"/Contents/Invoices/{OwnerID}/Co/{CompanyID}/"
Dim files() As String = Directory.GetFiles(Server.MapPath(InvoicePath))
Dim lst = GetInvoiceInfo(CInt(CompanyID), CInt(OwnerID))
For Each file As String In files
Dim InvNo As String = Path.GetFileNameWithoutExtension(file)
Dim InvNoFull As String = Path.GetFileName(file)
InvNo = InvNo.Substring(InvNo.LastIndexOf("_") + 1, InvNo.Length - InvNo.LastIndexOf("_") - 1)
Debug.Print(InvNo) 'To check your substring, will not be in release version
For Each i As Integer In lst
Dim s As String = i.ToString()
If s <> InvNo Then
Dim FileToDelete() As String
FileToDelete = Directory.GetFiles(Server.MapPath(InvoicePath & InvNoFull))
If System.IO.File.Exists(FileToDelete.ToString()) = True Then
System.IO.File.Delete(FileToDelete.ToString())
'MsgBox("File Deleted")
End If
End If
Next
Next
End Sub
The data retrieval is in a separate function. Use Using
blocks to make sure your connections and commands are closed and disposed. Always use parameters with Sql Server. There is a bit of Linq magic at the end to create the list from the DataTable
.
Private Function GetInvoiceInfo(CompanyID As Integer, OwnerID As Integer) As List(Of Integer)
Dim dt As New DataTable
Using cn As New SqlConnection(ConfigurationManager.ConnectionStrings("ClientConnectionString").ConnectionString),
cmd As New SqlCommand("select OrderBilling.OrderId
from orderBilling
Left Outer Join Orders on OrderBilling.OrderId = Orders.OrderId
Where Orders.CompanyId = @CompanyID
And Orders.OwnerId = @OwnerID
And OrderBilling.PaidInFull = @Paid;", cn)
cmd.Parameters.Add("@CompanyID", SqlDbType.Int).Value = CompanyID
cmd.Parameters.Add("@OwnerID", SqlDbType.Int).Value = OwnerID
cmd.Parameters.Add("@Paid", SqlDbType.Bit).Value = False
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
Dim lstOrderID As List(Of Integer) = (From dRow In dt.AsEnumerable() Select dRow.Field(Of Integer)(0)).ToList
Return lstOrderID
End Function
The actual deleting of the files (or moving to a Paid folder) is up to you.
Upvotes: 2