Ms-Access
將一張表上的 1 條記錄拆分為另一張表上的兩條記錄
我對此真的很陌生,所以請原諒我的無知,但我真的需要一些幫助!
我有兩個表:BillsFiled 和 Authors
在 BillsFiled 上,有以下列:ID、符號、文件日期、類型、作者、標題、摘要等
這是從導入的 Excel 文件中填充的,該文件由不關心我的引用完整性需求的外部源填充,這意味著“作者”欄位可以包含多個條目,例如:
ID-Symbol-------Filedate------Type------------Author--------------------Title--------------------Summary 1 - s001 ---- 11/18/2014 --- Resolution -- Smith ; Stevens ----- A Resolution to... ------- yadayada 2 - h002 ---- 11/18/2014 --- Bill ----------- Diaz -------------------- A Bill to... ----------------- yadayada 3 - s002 ---- 11/18/2014 ---- Bill --------- Ryan ; Smith ; Harris-- A bill... -------------------- yadayada
因為我需要將“作者”連結到“符號”的記錄,所以我也有一個表:作者。這僅包含列:符號和作者。
我最熱切的希望是執行查詢或一些 vba 或宏或其他東西來拆分“BillFiled”中的多個條目以附加“作者”,例如:
Symbol - Author s001 Smith s001 Stevens h002 Diaz s002 Ryan s002 Smith s002 Harris
我在這個網站上找到了大約一年前提供的一串程式碼,以回應另一個使用者的一個非常相似的問題,並嘗試使用它,但得到了奇怪的結果。程式碼(用我的表名和列名更新)是:
Sub SplitIt() Dim rstBillFiled As Recordset Dim rstAuthors As Recordset Dim Items() As String ' use dbOpenSnapshot to open the source table READ-ONLY Set rstBillFiled = CurrentDb.OpenRecordset( _ "SELECT Symbol, Author FROM BillFiled;" _ , dbOpenSnapshot) ' use dbOpenDynaset to open the destination table READ-WRITE Set rstAuthors = CurrentDb.OpenRecordset( _ "SELECT Symbol, Author FROM BillFiled;" _ , dbOpenDynaset) With rstBillFiled ' .BOF is Beginning of the table ' .EOF is End of the table ' Checking if both are false means there are records in the ' source table If Not (.BOF And .EOF) Then ' get the first record from the source table .MoveFirst Do ' if Author is NULL (empty) If Nz(!Author, "") = "" Then ' add a new record into the destination table ' with data from the source table for Symbol rstAuthors.AddNew rstAuthors!Symbol = rstBillFiled!Symbol ' set Author to NULL (empty) rstAuthors!Author = Null ' save the new record rstAuthors.Update Else ' if Author IS NOT NULL ' convert Author into an array of strings Items = Split(Nz(!Author, ""), ";") ' loop through the array of strings For a = LBound(Items) To UBound(Items) rstAuthors.AddNew rstAuthors!Symbol = rstBillFiled!Symbol ' Author is set to the current item in the array rstAuthors!Author = Items(a) rstAuthors.Update Next a End If ' load the next record from the source table .MoveNext ' repeat until the end of the source table is reached Loop Until .EOF End If ' close the source table rstBillFiled.Close End With ' close the destination table rstAuthors.Close End Sub
使用從立即視窗執行 SplitIt 的指令。
當我這樣做時,它會收集和拆分記錄,但所有記錄都被添加到“BillFiled”而不是“Authors”中
它還對前兩條記錄重複該操作,這樣如果源表中共有 4 條記錄可歸屬於 6 位作者,它將向源表添加 8 條新記錄,而對目標表則不添加任何記錄。
正如我一開始所說,我真的不知道自己在做什麼,也沒有任何程式碼經驗,但我正在嘗試建立這個數據庫來幫助沒有時間的家庭成員開展業務學習如何。我有一些時間,但遺憾的是我不知道,所以如果有人能同情我,並用你經驗豐富的眼睛來看待這件事,我將不勝感激!謝謝!
看看這是否有效。
CREATE FUNCTION [dbo].[FN_CommaSeparator] (@array VARCHAR(max)) > RETURNS @Table TABLE (value VARCHAR(max)) AS BEGIN DECLARE @separator_position INT ,@array_value VARCHAR(max) SET @array = @array + ',' WHILE PATINDEX('%,%', @array) <> 0 BEGIN SELECT @separator_position = PATINDEX('%,%', @array) SELECT @array_value = LEFT(@array, @separator_position - 1) INSERT @Table VALUES (@array_value) SELECT @array = STUFF(@array, 1, @separator_position, '') END RETURN END CREATE TABLE #Temp ( Id VARCHAR(10) ,Author VARCHAR(50) ) CREATE TABLE #Temp2 ( Id VARCHAR(10) ,Author VARCHAR(50) ) INSERT INTO dbo.#Temp ( Id ,Author ) VALUES ( 'S1' ,'ABC,BCD' ) ,( 'S2' ,'CDE,DEF' ) ,( 'S3' ,'EFG,FGH' ) ,( 'S4' ,'GHI,HIJ' ) DECLARE @Id VARCHAR(50) ,@Author VARCHAR(50) DECLARE ABC CURSOR FOR SELECT Id ,Author FROM dbo.#Temp t OPEN ABC FETCH NEXT FROM ABC INTO @Id ,@Author WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO dbo.#Temp2 ( Id ,Author ) SELECT @Id ,Value FROM dbo.FN_CommaSeparator(@Author) FETCH NEXT FROM ABC INTO @Id ,@Author END DEALLOCATE ABC SELECT * FROM dbo.#Temp2 t DROP TABLE dbo.#Temp DROP TABLE dbo.#Temp2
我遇到了類似的問題,並使用Pinal Dave的這種方法對其進行了整理:
CREATE TABLE #AuthorsList (ID INT, Author VARCHAR(50), Title VARCHAR(50)) INSERT INTO #AuthorsList (ID, Author, Title) VALUES (1,'Smith;Stevens','A Resolution to'); INSERT INTO #AuthorsList (ID, Author, Title) VALUES (2,'Diaz','A Bill to'); INSERT INTO #AuthorsList (ID, Author, Title) VALUES (3,'Ryan;Smith;Harris','A Something'); SELECT ID, LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS Authors, Title FROM ( SELECT ID, CAST('<XMLRoot><RowData>' + REPLACE(Author,';','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x, Title FROM #AuthorsList )t CROSS APPLY x.nodes('/XMLRoot/RowData')m(n)
結果:
ID Authors Title ------------------------------ 1 Smith A Resolution to 1 Stevens A Resolution to 2 Diaz A Bill to 3 Ryan A Something 3 Smith A Something 3 Harris A Something